├── .github └── workflows │ └── main.yml ├── .gitignore ├── .hypb ├── .mailmap ├── COPYING ├── ChangeLog ├── DEMO ├── DEMO-ROLO.otl ├── FAST-DEMO ├── HY-ABOUT ├── HY-ANNOUNCE ├── HY-CONCEPTS.kotl ├── HY-COPY ├── HY-NEWS ├── HY-TALK ├── .hypb ├── HY-TALK-ANNOUNCE.txt ├── HY-TALK.org ├── HYPB ├── HYPERAMP.org ├── HYPERORG.org ├── hbirds.gif └── org-mode-unicorn.png ├── HY-WHY.kotl ├── INSTALL ├── MANIFEST ├── Makefile ├── README.md ├── README.md.html ├── README.toc.md ├── _config.yml ├── _hypb ├── hact.el ├── hactypes.el ├── hargs.el ├── hasht.el ├── hbdata.el ├── hbmap.el ├── hbut.el ├── hgnus.el ├── hhist.el ├── hib-debbugs.el ├── hib-doc-id.el ├── hib-kbd.el ├── hib-social.el ├── hibtypes.el ├── hinit.el ├── hload-path.el ├── hmail.el ├── hmh.el ├── hmoccur.el ├── hmouse-drv.el ├── hmouse-info.el ├── hmouse-key.el ├── hmouse-mod.el ├── hmouse-sh.el ├── hmouse-tag.el ├── hpath.el ├── hproperty.el ├── hrmail.el ├── hsettings.el ├── hsmail.el ├── hsys-consult.el ├── hsys-ert.el ├── hsys-flymake.el ├── hsys-org-roam.el ├── hsys-org.el ├── hsys-www.el ├── hsys-xref.el ├── hsys-youtube.el ├── htz.el ├── hui-dired-sidebar.el ├── hui-jmenu.el ├── hui-menu.el ├── hui-mini.el ├── hui-mouse.el ├── hui-register.el ├── hui-select.el ├── hui-treemacs.el ├── hui-window.el ├── hui.el ├── hvar.el ├── hversion.el ├── hycontrol.el ├── hynote.el ├── hypb-ert.el ├── hypb-maintenance.el ├── hypb.el ├── hyperbole-banner.png ├── hyperbole.el ├── hyrolo-demo.el ├── hyrolo-logic.el ├── hyrolo-menu.el ├── hyrolo.el ├── hyrolo.py ├── hywconfig.el ├── hywiki.el ├── hywiki ├── HyWiki.org ├── HyWikiMenus.org └── Publishing.org ├── install-test ├── MANIFEST ├── elpa-devel │ └── .emacs ├── elpa │ └── .emacs ├── elpaca │ └── .emacs ├── local-install-test.sh ├── local │ └── .emacs ├── melpa │ └── .emacs ├── straight │ └── .emacs └── tarball │ ├── .emacs │ └── install-local.sh ├── interactive-demos ├── HYPERBOLE └── HYROLO ├── kotl ├── EXAMPLE.kotl ├── MANIFEST ├── kcell.el ├── kexport.el ├── kfile.el ├── kfill.el ├── kimport.el ├── klabel.el ├── klink.el ├── kmenu.el ├── kotl-mode.el ├── kotl-orgtbl.el ├── kproperty.el ├── kview.el └── kvspec.el ├── man ├── .dir-locals.el ├── dir ├── hkey-help.txt ├── hyperbole.css ├── hyperbole.html ├── hyperbole.info ├── hyperbole.pdf ├── hyperbole.texi ├── im │ ├── C-hh.png │ ├── action-key-animation.gif │ ├── demo.png │ ├── hyperbole-cv.png │ ├── koutliner.png │ ├── menu-customization.png │ ├── menu-display-referents.png │ ├── menu-find.png │ ├── menu-hyperbole.png │ ├── menu-key-bindings.png │ ├── menu-koutline.png │ ├── menu-rolo.png │ ├── menu-url-browser.png │ ├── menu-web-search-browser.png │ ├── wgrid-2x2.png │ ├── wgrid-2x3.png │ ├── wgrid-3x5.png │ └── wgrid-4x6.png └── texinfo-7.css ├── set.el ├── smart-clib-sym ├── test ├── MANIFEST ├── demo-tests.el ├── hact-tests.el ├── hactypes-tests.el ├── hargs-tests.el ├── hbut-tests.el ├── hib-kbd-tests.el ├── hib-social-tests.el ├── hibtypes-resources │ ├── TAGS │ └── test-data.el ├── hibtypes-tests.el ├── hmouse-drv-resources │ ├── TAGS │ └── test-data.el ├── hmouse-drv-tests.el ├── hmouse-info-tests.el ├── hpath-tests.el ├── hproperty-tests.el ├── hsettings-test.el ├── hsys-org-tests.el ├── hui-mini-tests.el ├── hui-mouse-tests.el ├── hui-register-tests.el ├── hui-select-tests.el ├── hui-tests.el ├── hy-test-coverage.el ├── hy-test-dependencies.el ├── hy-test-helpers.el ├── hycontrol-tests.el ├── hypb-ert-tests.el ├── hypb-tests.el ├── hyperbole-tests.el ├── hyrolo-tests.el ├── hywconfig-tests.el ├── hywiki-tests.el ├── kcell-tests.el ├── kexport-tests.el ├── kimport-tests.el ├── kotl-mode-tests.el ├── kotl-orgtbl-tests.el ├── set-tests.el ├── smart-org-tests.el └── test-helpers-tests.el └── topwin.py /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: [ "master" ] 6 | pull_request: 7 | branches: [ "master" ] 8 | 9 | workflow_dispatch: 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | strategy: 15 | fail-fast: false 16 | matrix: 17 | version: [28.2, 29.4, 30.1, master] 18 | container: silex/emacs:${{ matrix.version }}-ci 19 | 20 | steps: 21 | - uses: actions/checkout@v4 22 | 23 | - name: Clean 24 | run: make clean 25 | 26 | - name: Compile 27 | shell: bash 28 | run: | 29 | make bin 2>&1 | tee MAKE_BIN_OUTPUT 30 | echo "Number of warnings: $(grep "Warning:" MAKE_BIN_OUTPUT | wc -l)" >> $GITHUB_STEP_SUMMARY 31 | echo '```' >> $GITHUB_STEP_SUMMARY 32 | grep "Warning:" MAKE_BIN_OUTPUT >> $GITHUB_STEP_SUMMARY || true 33 | echo '```' >> $GITHUB_STEP_SUMMARY 34 | 35 | - name: Test 36 | run: make test 37 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Files that Git should ignore in the GNU Hyperbole source directory. 2 | 3 | *-autoloads.el 4 | *-pkg.el 5 | 6 | # Copyright (C) 2016-2019 Free Software Foundation, Inc. 7 | # See the "HY-COPY" file for license information. 8 | 9 | # This file is part of GNU Hyperbole. 10 | 11 | # Object files 12 | *.elc 13 | 14 | # Version control and locks. 15 | *.orig 16 | *.rej 17 | *~ 18 | \.#* 19 | 20 | # Texinfo formatting indices 21 | *.aux 22 | *.cps? 23 | *.fns? 24 | *.kys? 25 | *.toc 26 | *.vrs? 27 | 28 | # Todo working files 29 | TODO* 30 | 31 | # Programming support 32 | 33 | # Video Demos 34 | videos 35 | -------------------------------------------------------------------------------- /.hypb: -------------------------------------------------------------------------------- 1 | 2 | "HY-CONCEPTS.kotl" 3 | ("Explicit_buttons" nil nil link-to-Info-node ("(hyperbole)Explicit Buttons") "rsw@gnu.org" "20230513:19:36:50" nil nil) 4 | 5 | "ChangeLog" 6 | ("td" nil nil link-to-ibut ("td" "/Users/bk/.hyperb/HYPB") "rsw@gnu.org" "20230205:16:38:15" nil nil) 7 | 8 | "BUG-TESTS" 9 | ("ftp_tests" nil nil link-to-file-line ("./DEMO" 678) "rsw@gnu.org" "20210418:23:05:20" "rsw" "20210418:23:15:25") 10 | 11 | "DEMO" 12 | ("electric_car" nil nil link-to-web-search ("Wikipedia" "electric car") "rsw@gnu.org" "20160809:03:19:05" "rsw" "20160809:03:20:24") 13 | ("hyperbole-web-search-alist" nil nil eval-elisp ((customize-variable (quote hyperbole-web-search-alist))) "rsw@gnu.org" "20160805:17:32:16" nil nil) 14 | ("button" nil nil eval-elisp ((hkey-summarize)) "rsw@gnu.org" "20160623:05:52:14" nil nil) 15 | ("Smart_Mouse_Keys" nil nil link-to-string-match ("* Smart Mouse Keys" 1 "./DEMO") "rsw" "19940530:05:17:23" nil nil) 16 | ("as_long_as_you_click_within_its_first_line" nil nil eval-elisp ((message "Hyperbole simplifies your work.")) "rsw@gnu.org" "19921024:23:08:43" nil nil) 17 | ("factorial_button" nil nil link-to-ebut ("factorial" "./DEMO") "rsw@gnu.org" "19921014:18:57:35" nil nil) 18 | ("toggle-scroll-proportional" nil nil eval-elisp ((progn (setq smart-scroll-proportional (not smart-scroll-proportional)) (message "smart-scroll-proportional = %s" smart-scroll-proportional))) "rsw@gnu.org" "19920923:05:33:32" nil nil) 19 | ("glossary" nil nil link-to-Info-node ("(hyperbole)Glossary") "rsw@gnu.org" "19911210:07:11:29" "rsw" "20160627:21:31:31") 20 | (".emacs" nil nil link-to-file ("~/.emacs") "rsw@gnu.org" "19911126:05:01:08" "rsw" "20160627:21:35:42") 21 | ("tmp_directory" nil nil link-to-directory ("/tmp") "rsw@gnu.org" "19911126:04:03:37" nil nil) 22 | ("Info-directory" nil nil eval-elisp ((message "Info-directory = %s" Info-directory)) "rsw@gnu.org" "19911126:03:46:54" nil nil) 23 | ("keyboard_macros" nil nil link-to-Info-node ("(emacs)Keyboard Macros") "rsw@gnu.org" "19911126:01:08:12" nil nil) 24 | ("factorial_alias" nil nil link-to-ebut ("factorial" "./DEMO") "rsw@gnu.org" "19911126:00:54:30" "rsw" "19911126:00:56:10") 25 | ("maximum_length" nil nil eval-elisp ((message "Max length of explicit button labels = %d characters." ebut:max-len)) "rsw@gnu.org" "19911126:00:48:26" nil nil) 26 | ("shell_command" nil nil exec-shell-cmd ("ls -l DEMO" nil nil) "rsw@gnu.org" "19911126:00:42:32" "rsw" "19911213:19:07:43") 27 | ("keyboard_macro" nil nil exec-kbd-macro ("(f " 1) "rsw@gnu.org" "19911126:00:38:11" nil nil) 28 | ("factorial" nil nil eval-elisp ((message "Factorial of 5 = %d" (* 5 4 3 2))) "rsw@gnu.org" "19911125:09:52:22" "rsw" "19911125:09:54:00") 29 | -------------------------------------------------------------------------------- /.mailmap: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Bob Weiner bw 5 | Bob Weiner Robert Weiner 6 | Bob Weiner Kathy 7 | Bob Weiner Barbara Weiner 8 | 9 | -------------------------------------------------------------------------------- /DEMO-ROLO.otl: -------------------------------------------------------------------------------- 1 | ================================================================== 2 | DEMO ROLO 3 | ================================================================== 4 | * HiHo Industries 5 | ** Strong, Hugo W708-555-9821 6 | Manager of Buttons 7 | 04/12/2017 8 | *** Smith, John W708-555-2001 9 | Chief Ether Maintainer 10 | 05/24/2017 11 | * Work Industries 12 | ** Hansen, Dan W218-555-2311 13 | Manager of Clasps 14 | 02/18/2017 15 | *** Dunn, John W218-555-3233 16 | Media Maker 17 | 11/2/2017 18 | -------------------------------------------------------------------------------- /HY-ANNOUNCE: -------------------------------------------------------------------------------- 1 | From: Bob Weiner 2 | To: gnu-emacs-sources@gnu.org, emacs-tangents@gnu.org, hyperbole-users@gnu.org, hyperbole-announce@gnu.org 3 | Subject: GNU Hyperbole Major Release 9 (V9.0.2pre) 4 | --text follows this line-- 5 | ======================================================================== 6 | * Overview 7 | ======================================================================== 8 | 9 | Still in development. 10 | -------------------------------------------------------------------------------- /HY-COPY: -------------------------------------------------------------------------------- 1 | =========================================================================== 2 | * Copyright 3 | =========================================================================== 4 | 5 | The following copyright applies to the GNU Hyperbole software. 6 | 7 | Copyright (C) 1989-2024 Free Software Foundation, Inc. 8 | 9 | Originally developed with support from Motorola Inc., who donated all 10 | such work to the Free Software Foundation, Inc. in the 1990s. 11 | 12 | Hyperbole is available for use, modification, and distribution under 13 | the terms of the GNU General Public License (GPL) Version 3, or (at 14 | your option) any later version as published by the Free Software 15 | Foundation, with all rights and responsibilities thereof. 16 | 17 | Hyperbole is offered in the hope that it will be useful, but WITHOUT 18 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 19 | FITNESS FOR A PARTICULAR PURPOSE. 20 | 21 | See the GNU General Public License in the file, "COPYING", in this 22 | directory for more details. 23 | -------------------------------------------------------------------------------- /HY-TALK/.hypb: -------------------------------------------------------------------------------- 1 | 2 | "HYPERAMP.org" 3 | ("ERT_test" nil nil link-to-file ("../test/hbut-tests.el#hypb:program-create-ebut-in-buffer") "rsw@gnu.org" "20231203:01:48:10" nil nil) 4 | 5 | "HYPERORG.org" 6 | ("Bring_Your_Text_to_Life" nil nil life (1) "rsw@gnu.org" "20221204:08:36:54" nil nil) 7 | 8 | "HY-TALK.org" 9 | ("Make_Your_Text_Come_Alive" nil nil kbd-key ("C-x 1 C-x 2 C-x o M-x hanoi RET") "rsw@gnu.org" "20200803:20:10:07" "rsw" "20200803:20:14:20") 10 | ("GNU_Hyperbole" nil nil link-to-file ("${hyperb:dir}/hyperbole-banner.png" 7049) "rsw@gnu.org" "20200803:20:08:40" nil nil) 11 | 12 | "HYPB" 13 | ("Hyperbole_Todos" nil nil link-to-file ("${hyperb:dir}/Todo.txt" 422) "rsw@gnu.org" "20200803:15:14:32" nil nil) 14 | ("line-count" nil nil eval-elisp ((message "Lines in %s = %s" (buffer-name) (count-lines (point-min) (point-max)))) "rsw@gnu.org" "20200301:17:56:53" nil nil) 15 | -------------------------------------------------------------------------------- /HY-TALK/HY-TALK-ANNOUNCE.txt: -------------------------------------------------------------------------------- 1 | Bring Your Text to Life the Easy Way with GNU Hyperbole 2 | 3 | A talk by the author, Bob Weiner 4 | 5 | 6 | Like Emacs itself, GNU Hyperbole is an integrated, extensible, 7 | self-documenting, and programmable hypertextual editing environment 8 | delivered as a single ELPA package for quick installation and 9 | evaluation. But where to start with such a large package? 10 | 11 | This talk will provide a detailed, interactive overview of GNU 12 | Hyperbole's major capabilities and how they can speed knowledge 13 | work, including: 14 | 15 | 1. Implicit, Explicit and Global Buttons for interlinking your 16 | textual information regardless of type or mode; 17 | 18 | 2. Org Mode Integration that reduces the complexity of dealing with 19 | Org constructs and lets you leverage Hyperbole in Org documents; 20 | 21 | 3. The Koutliner for rapid outlining with multi-level autonumbering 22 | (like legal numbering), per outline heading/cell permanent 23 | hyperlink anchors, and dynamic views that can be triggered by 24 | links themselves; 25 | 26 | 4. HyRolo for fast contact or any hierarchical record management 27 | including Org files or normal Emacs outlines; 28 | 29 | 5. HyControl for fast control over your Emacs windows and frames: 30 | interactively increase or decrease your your face sizes, adjust 31 | window sizes and layouts; replicate frame sizes and attributes 32 | precisely; show what you want where you want it. 33 | 34 | Whatever you like about Emacs you'll likely find similar in Hyperbole. 35 | Hyperbole grows with you as your knowledge and work complexity 36 | increases. An hour invested in Hyperbole has the potential to save 37 | you hundreds of hours in your future knowledge work. Come find out 38 | about the magic and why its not all hyperbole. 39 | -------------------------------------------------------------------------------- /HY-TALK/HYPB: -------------------------------------------------------------------------------- 1 | * Use org-present package to turn Org outline into a presentation 2 | you can step through with the space and delete keys. 3 | 4 | Install: 5 | 6 | (defun rsw-org-present-setup (buffer-name heading) 7 | ;; Don't hide headline stars 8 | (setq org-present-hide-stars-in-headings nil 9 | ;; org-present-startup-folded nil 10 | org-hide-emphasis-markers nil) 11 | 12 | (setq org-present-text-scale 3) 13 | 14 | ;; Show only top-level headlines 15 | (org-overview) 16 | 17 | ;; Unfold the current entry 18 | (org-show-entry) 19 | 20 | ;; Show only direct subheadings of the slide but don't expand them 21 | (org-show-children)) 22 | 23 | (add-hook 'org-present-after-navigate-functions 'rsw-org-present-setup) 24 | 25 | (add-hook 'org-present-mode-hook 26 | (lambda () 27 | (org-present-big) 28 | (org-display-inline-images))) 29 | 30 | (add-hook 'org-present-mode-quit-hook 31 | (lambda () 32 | (org-present-small) 33 | (org-remove-inline-images))) 34 | 35 | * Enable all Hyperbole keys including {M-RET} in Org mode 36 | 37 | 38 | 39 | * How to setup button2 and button3 as Action and Assist Mouse Keys 40 | 41 | Add to your Emacs init file: 42 | 43 | (eval-after-load "hyperbole" '(hmouse-add-unshifted-smart-keys)) 44 | 45 | or interactively after loading Hyperbole: 46 | 47 | 48 | 49 | * Keystroke Display 50 | 51 | ** interaction-log Package - font-lock highlighted log of keys and commands 52 | Used for EmacsConf 2022 53 | 54 | Install, 55 | Load, 56 | Configure, 57 | Activate: 58 | Deactivate: 59 | 60 | ** ALTERNATIVE: Keypression - overlaying parts of buffer (shows trail of keys) 61 | Used for EmacsNYC talk 62 | 63 | Install: 64 | Activate: 65 | Deactivate: 66 | 67 | Configure: 68 | 75 | 76 | * Frame layout 77 | 78 | 79 | 80 | 81 | * Pathname Prefixes 82 | 83 | "!${PATH}/date" - execute 'date' shell command 84 | 85 | "&open ${hyperb:dir}/man/hyperbole.pdf" 86 | 87 | "-subr" - load an Elisp library 88 | 89 | * Programming Buttons 90 | 91 | Emacs Yank Bug: bug#5320 92 | 93 | * Global Buttons 94 | 95 | <[Test ibut label]> {C-u C-n} 96 | 97 | <[Bufs]> {C-x C-b} 98 | 99 | <[iPython src]>: "/usr/local/Cellar/ipython/7.16.1/libexec/lib/python3.8/site-packages/IPython/" 100 | - Goto <(Hyperbole Todos)> 101 | 102 | <[ib]> "(hyperbole)Implicit Buttons" 103 | <[frm]> "(hyperbole)C-h h s f" 104 | 105 | "${hyperb:dir}/DEMO" 106 | 107 | "${hyperb:dir}/README.md#Programmer Quick Reference:4:2" 108 | "${hyperb:dir}/README.md#programmer-quick-reference:4:2" 109 | 110 | 111 | 112 | <[PDF Viewer]> == "${hyperb:dir}/man/hyperbole.pdf" 113 | -------------------------------------------------------------------------------- /HY-TALK/HYPERAMP.org: -------------------------------------------------------------------------------- 1 | -*- Mode: org; org-cycle-global-at-bob: t; hsys-org-enable-smart-keys: t -*- 2 | 3 | #+TITLE: Top 10 Ways Hyperbole Amps Up Emacs 4 | #+AUTHOR: Robert Weiner 5 | 6 | `GNU Hyperbole' (pronounced Ga-new Hi-per-bo-lee), or just `Hyperbole', is 7 | like Markdown for hypertext. Hyperbole automatically recognizes dozens of 8 | common, pre-existing patterns in any buffer regardless of mode and can 9 | instantly activate them as hyperbuttons with a single key: email addresses, 10 | URLs, grep -n outputs, programming backtraces, sequences of Emacs keys, 11 | programming identifiers, Texinfo and Info cross-references, Org links, 12 | Markdown links and on and on. All you do is load Hyperbole and then your 13 | text comes to life with no extra effort or complex formatting. 14 | 15 | Install Hyperbole: (progn (require 'package) 16 | (add-to-list 'package-archives 17 | '("elpa-devel" . "https://elpa.gnu.org/devel/")) 18 | (package-install 'hyperbole)) 19 | 20 | Activate Hyperbole: {C-h h} - displays minibuffer menu 21 | Reference Manual: "(hyperbole)Top" 22 | 23 | Hyperbole Demo: {C-h h d d} - interactive demo/tutorial as introduction 24 | 25 | Display Keys: 26 | Hide Keys: 27 | Erase Key Log: 28 | 29 | Let's countdown the top 10 ways Hyperbole can help you. We'll move 30 | fast as we have a lot to cover in a short time. We'll answer 31 | questions after the talk. 32 | 33 | * 10. Key Series - in-buffer automation for everything 34 | 35 | ** Key series are curly brace, {}, delimited hyperbuttons that are an 36 | in-buffer substitute for keyboard macros. 37 | 38 | Place them in any file (in comment lines for programming files). 39 | 40 | Then press {M-RET} within one to activate it. 41 | 42 | {M-x shell RET M-> (export HYPERBOLE_DIR=${hyperb:dir} && 43 | cd $HYPERBOLE_DIR && grep -n gbut:label-list *.el) RET} 44 | 45 | Use both a Hyperbole resolved variable, ${hyperb:dir}, and a 46 | shell-resolved environment variable, $HYPERBOLE_DIR, to grep through 47 | Lisp files. 48 | 49 | {C-h h h} will restore your windows after invoking the above key series. 50 | 51 | ** FYI, Hyperbole offers a simpler way to recursively grep your current directory 52 | for just Elisp files. Use 'hypb:rgrep' when in an Elisp buffer and it will 53 | match to only Elisp files. 54 | 55 | {C-x 1 C-x 3 C-x o C-x C-f hibtypes.el RET C-x o C-n C-n} 56 | 57 | {C-x o M-x hypb:rgrep RET gbut:label-list RET C-x o C-x 1 C-x 3 C-x b HYPERAMP RET} 58 | 59 | * 9. Existing pathnames with Environment or Lisp variables are hyperbuttons too 60 | 61 | ${PATH}/rgrep 62 | 63 | "${hyperb:dir}/README.md#Programmer Quick Reference:5:5" 64 | "${hyperb:dir}/README.md#programmer-quick-reference:4:2" 65 | 66 | ~/.bashrc#Alias 67 | 68 | "${hyperb:dir}/kotl/EXAMPLE.kotl#3c" 69 | "${hyperb:dir}/kotl/EXAMPLE.kotl#3c|c2ben" 70 | 71 | * 8. File prefixes for special handling 72 | 73 | "-subr" - load an Elisp library 74 | 75 | "!${PATH}/date" - execute 'date' shell command 76 | 77 | "&xdg-open ${hyperb:dir}/man/hyperbole.pdf" - run a graphical PDF viewer 78 | 79 | * 7. Bookmarks on Steroids 80 | 81 | {C-x 2 C-x o C-h h b p} - Your personal home page of buttons and bookmarks 82 | 83 | {C-h h g a} - Activate by name 84 | 85 | * 6. Instant test case running and debugging 86 | 87 | {M-RET} on the first line of an <(ERT test)> runs it. 88 | 89 | {C-u M-RET} steps through it with the edebugger. 90 | 91 | * 5. Instant 2-window typed hyperlink creation 92 | 93 | Place 2 windows on screen; place point where you want to link to in one 94 | window and then move to the window where you want the hyperlink placed. 95 | 96 | {C-h h i l} will create a typed implicit link at point. 97 | {C-h h e l} will create an explicit link instead. 98 | {C-h h g l} will create a global named implicit link that works like a bookmark. 99 | 100 | * 4. Koutliner - Instant collapsible outlines on the web 101 | 102 | {C-x 1 C-x 2} 103 | {C-h h k e} 104 | 105 | {C-x o C-h h k} - Koutliner menu 106 | 107 | {f d} - Format menu, then display in browser 108 | 109 | * 3. HyControl - Zoom font size across all faces, windows and frames at once 110 | 111 | {C-x 1 C-x 3 M-x list-faces-display RET C-x o} 112 | 113 | {C-h h s f} - {z} zoom out all frames; {Z} zoom in all frames 114 | 115 | {C-h h s w} - {z} zoom out all frames; {Z} zoom in all frames 116 | 117 | * 2. HyRolo - Simple, fast, flexible hierarchical record management 118 | 119 | ** Search across Org, Emacs outline, Markdown and Koutline files and multiple dirs 120 | 121 | 123 | 124 | {C-h h r s button RET} 125 | 126 | ** Dynamic line-level filtering with Consult 127 | 128 | {C-x 1 C-x 3 C-x o} 129 | 130 | 131 | 132 | * 1. Custom Implicit Button Types - solve your own problems 133 | 134 | 135 | ** defal - Create new button types with no programming knowledge 136 | 137 | (defal ddg "https://duckduckgo.com/?q=\"%s\"") 138 | 139 | 140 | 141 | ** defil - Control the way your link buttons look 142 | 143 | Here is a sample use case. Create a button type whose buttons 144 | perform a grep-like function over a current repository’s git 145 | log entries. The buttons use this format: []. 146 | 147 | The following defines the button type called search-git-log which 148 | calls hypb:fgrep-git-log with the text of the button as an argument: 149 | 150 | (defil search-git-log "[<" ">]" ".*" #'hypb:fgrep-git-log) 151 | 152 | [] 153 | 154 | ** defib - Use full Emacs Lisp to define button types (see "hibtypes.el") 155 | 156 | (progn 157 | (require 'thingatpt) 158 | (defib dow () 159 | "Display a message with DATE's (YYYY-MM-DD) day of the week." 160 | (let ((date (thing-at-point 'sexp))) 161 | (when (and (stringp date) 162 | (string-match-p "[0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}" 163 | date)) 164 | (cl-destructuring-bind (_ignore _ignore _ignore day month year _ignore _ignore _ignore) (parse-time-string date) 165 | (hact #'message "%s falls on %s" date 166 | (calendar-day-name (list month day year)))))))) 167 | 168 | 2023-12-03 169 | 2023-12-05 170 | 171 | * Thanks 172 | 173 | - To my co-maintainer Mats Lidell 174 | 175 | - To all the hard-working volunteers and speakers at EmacsConf 176 | 177 | -- The End -- 178 | 179 | -------------------------------------------------------------------------------- /HY-TALK/hbirds.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rswgnu/hyperbole/db9f64b3489543b7d16ec930f69c9db34e5b70ae/HY-TALK/hbirds.gif -------------------------------------------------------------------------------- /HY-TALK/org-mode-unicorn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rswgnu/hyperbole/db9f64b3489543b7d16ec930f69c9db34e5b70ae/HY-TALK/org-mode-unicorn.png -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman -------------------------------------------------------------------------------- /_hypb: -------------------------------------------------------------------------------- 1 | 2 | "TODO" 3 | ("hui-menu-hywconfig" nil nil link-to-file ("${hyperb:dir}/hui-jmenu.el" 4545) "rsw@gnu.org" "20171019:18:22:27" nil nil) 4 | ("hmouse-window-at-absolute-pixel-position" nil nil link-to-string-match ("(defun hmouse-window-at-absolute-pixel-position (&optional position release-flag)" 1 "${hyperb:dir}/hmouse-drv.el") "rsw@gnu.org" "20171017:01:59:48" nil nil) 5 | ("Ftp_and_Git_Source_Code-only_Downloads" nil nil link-to-string-match ("## Ftp and Git Source Code-only Downloads" 1 "${load-path}/README.md") "rsw@gnu.org" "20171009:04:44:48" nil nil) 6 | ("macOS_mouseUp_handler" nil nil link-to-file ("/Users/bk/Dropbox/emacs/emacs26/src/nsterm.m" 203444) "rsw@gnu.org" "20171004:20:32:47" nil nil) 7 | ("Reduces_some_drags_to_a_click" nil nil link-to-file ("/Users/bk/sw-dev/emacs/emacs26/src/keyboard.c" 287483) "rsw@gnu.org" "20171004:17:07:51" nil nil) 8 | ("Button_Release_Event_Handling" nil nil link-to-string-match (" else if (event->modifiers & up_modifier)" 1 "../emacs26/src/keyboard.c") "rsw@gnu.org" "20171004:05:00:09" "rsw" "20171004:17:58:56") 9 | ("FocusIn_and_Mouse_Event_Generation" nil nil link-to-file ("../emacs26/src/keyboard.c" 175796) "rsw@gnu.org" "20171004:04:58:19" "rsw" "20171004:17:59:08") 10 | ("Test" nil nil link-to-file ("${hyperb:dir}/hui.el" 25328) "rsw@gnu.org" "20171002:18:50:03" "rsw" "20171002:21:43:17") 11 | ("hmouse-key-release-args-emacs" nil nil link-to-file ("/Users/bk/Dropbox/emacs/hyperbole/${hyperb:dir}/hmouse-drv.el" 21159) "rsw@gnu.org" "20170930:23:54:14" "rsw" "20171002:18:17:47") 12 | ("there" nil nil link-to-file ("/Users/bk/sw-dev/emacs/hyperbole-5.15/TODO-DEFCUSTOMS" 4008) "rsw@gnu.org" "20160713:14:53:04" nil nil) 13 | ("hui:link-possible-types" nil nil link-to-string-match ("(defun hui:link-possible-types ()" 1 "${hyperb:dir}/hui.el") "rsw@gnu.org" "20160701:22:21:23" "rsw" "20170925:04:52:29") 14 | ("kfill:forward-line" nil nil link-to-file ("${hyperb:dir}/kotl/kfill.el" 3563) "rsw@gnu.org" "20160511:12:28:30" nil nil) 15 | 16 | "DEMO" 17 | ("electric_car" nil nil link-to-web-search ("Wikipedia" "electric car") "rsw@gnu.org" "20160809:03:19:05" "rsw" "20160809:03:20:24") 18 | ("hyperbole-web-search-alist" nil nil eval-elisp ((customize-variable (quote hyperbole-web-search-alist))) "rsw@gnu.org" "20160805:17:32:16" nil nil) 19 | ("button" nil nil eval-elisp ((hkey-summarize)) "rsw@gnu.org" "20160623:05:52:14" nil nil) 20 | ("Smart_Mouse_Keys" nil nil link-to-string-match ("* Smart Mouse Keys" 1 "./DEMO") "rsw" "19940530:05:17:23" nil nil) 21 | ("as_long_as_you_click_within_its_first_line" nil nil eval-elisp ((message "Hyperbole simplifies your work.")) "rsw@gnu.org" "19921024:23:08:43" nil nil) 22 | ("factorial_button" nil nil link-to-ebut ("./DEMO" "factorial") "rsw@gnu.org" "19921014:18:57:35" nil nil) 23 | ("toggle-scroll-proportional" nil nil eval-elisp ((progn (setq smart-scroll-proportional (not smart-scroll-proportional)) (message "smart-scroll-proportional = %s" smart-scroll-proportional))) "rsw@gnu.org" "19920923:05:33:32" nil nil) 24 | ("glossary" nil nil link-to-Info-node ("(hyperbole)Glossary") "rsw@gnu.org" "19911210:07:11:29" "rsw" "20160627:21:31:31") 25 | (".emacs" nil nil link-to-file ("/Users/bk/Dropbox/emacs/.emacs") "rsw@gnu.org" "19911126:05:01:08" "rsw" "20160627:21:35:42") 26 | ("tmp_directory" nil nil link-to-directory ("/tmp") "rsw@gnu.org" "19911126:04:03:37" nil nil) 27 | ("Info-directory" nil nil eval-elisp ((message "Info-directory = %s" Info-directory)) "rsw@gnu.org" "19911126:03:46:54" nil nil) 28 | ("keyboard_macros" nil nil link-to-Info-node ("(emacs)Keyboard Macros") "rsw@gnu.org" "19911126:01:08:12" nil nil) 29 | ("factorial_alias" nil nil link-to-ebut ("./DEMO" "factorial") "rsw@gnu.org" "19911126:00:54:30" "rsw" "19911126:00:56:10") 30 | ("maximum_length" nil nil eval-elisp ((message "Max length of explicit button labels = %d characters." ebut:max-len)) "rsw@gnu.org" "19911126:00:48:26" nil nil) 31 | ("shell_command" nil nil exec-shell-cmd ("ls -l DEMO" nil nil) "rsw@gnu.org" "19911126:00:42:32" "rsw" "19911213:19:07:43") 32 | ("keyboard_macro" nil nil exec-kbd-macro ("(f " 1) "rsw@gnu.org" "19911126:00:38:11" nil nil) 33 | ("factorial" nil nil eval-elisp ((message "Factorial of 5 = %d" (* 5 4 3 2))) "rsw@gnu.org" "19911125:09:52:22" "rsw" "19911125:09:54:00") 34 | -------------------------------------------------------------------------------- /hbmap.el: -------------------------------------------------------------------------------- 1 | ;;; hbmap.el --- GNU Hyperbole button map maintenance for queries and lookups. -*- lexical-binding: t; -*- 2 | ;; 3 | ;; Author: Bob Weiner 4 | ;; 5 | ;; Orig-Date: 6-Oct-91 at 06:34:05 6 | ;; Last-Mod: 5-Jan-25 at 12:00:29 by Bob Weiner 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 1991-2021 Free Software Foundation, Inc. 11 | ;; See the "HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | 15 | ;;; Commentary: 16 | 17 | ;;; Code: 18 | ;;; ************************************************************************ 19 | ;;; Other required Elisp libraries 20 | ;;; ************************************************************************ 21 | 22 | (require 'hypb) 23 | 24 | ;;; ************************************************************************ 25 | ;;; Public variables 26 | ;;; ************************************************************************ 27 | 28 | (defvar hbmap:filename "HYPB" 29 | "*Filename used for quick access button files.") 30 | 31 | ;;; ************************************************************************ 32 | ;;; Private variables 33 | ;;; ************************************************************************ 34 | 35 | (defvar hyperb:microsoft-os-p) ; Defined in hload-path. 36 | 37 | (defvar hbmap:dir-user 38 | (if (and hyperb:microsoft-os-p 39 | (not (getenv "HOME"))) 40 | "c:/_hyperb/" "~/.hyperb/") 41 | "Per user directory in which to store top level Hyperbole map data. 42 | Must end with a directory separator. 43 | Hyperbole will try to create it whenever `hyperb:init' is called.") 44 | 45 | (defvar hbmap:dir-filename 46 | (expand-file-name "HBMAP" hbmap:dir-user) 47 | "Name of a file that lists all dirs to which a user has written buttons. 48 | See also `hbmap:dir-user'. 49 | If you change its value, you will be unable to search for buttons created by 50 | others who use a different value!") 51 | 52 | ;;; ************************************************************************ 53 | ;;; Public functions 54 | ;;; ************************************************************************ 55 | 56 | (defun hbmap:dir-add (dir-name &optional no-save) 57 | "Add DIR-NAME to map of all directories in which user has written buttons. 58 | Returns t iff DIR-NAME is not already in map, nil if it is, and some 59 | other value when cannot read or write map. 60 | Optional NO-SAVE disables saving of the map after an add." 61 | (hbmap:dir-operate (lambda (dir) (not (hbmap:dir-member dir))) 62 | dir-name 63 | `(progn (prin1 (list ,dir-name) (current-buffer)) 64 | (terpri (current-buffer))) 65 | no-save)) 66 | 67 | (defun hbmap:dir-list () 68 | "Return list of all directories in which user has written buttons." 69 | (save-excursion 70 | (let ((buf (unless (and (file-exists-p hbmap:dir-filename) 71 | (not (file-readable-p hbmap:dir-filename))) 72 | (find-file-noselect hbmap:dir-filename))) 73 | dirs) 74 | (when buf 75 | (set-buffer buf) 76 | (goto-char (point-min)) 77 | (condition-case () 78 | (while (setq dirs (cons (car (read (current-buffer))) 79 | dirs))) 80 | (error t)) 81 | dirs)))) 82 | 83 | (defun hbmap:dir-remove (dir-name &optional no-save) 84 | "Remove DIR-NAME from map of all dirs in which user has written buttons. 85 | Returns t iff DIR-NAME is in the map and is successfully removed, nil if it 86 | is not, and some other value when the map is not readable or writable. 87 | Optional NO-SAVE disables saving of the map after a removal." 88 | (hbmap:dir-operate 'hbmap:dir-member dir-name 89 | '(delete-region (point) (progn (forward-line 1) (point))) 90 | no-save)) 91 | 92 | (defun hbmap:dir-member (dir-name) 93 | "Return t iff DIR-NAME is a member of user's Hyperbole map, else nil. 94 | If t, point is left at the start of the matching map entry. If nil, 95 | point is left in a position appropriate for insertion of a new entry." 96 | (let ((obuf (current-buffer)) 97 | (buf (and (file-exists-p hbmap:dir-filename) 98 | (find-file-noselect hbmap:dir-filename))) 99 | rtn) 100 | (if buf 101 | (progn (set-buffer buf) (widen) (goto-char 1) 102 | (if (search-forward (concat "\n(\"" dir-name "\"") nil t) 103 | (progn (beginning-of-line) (setq rtn t)) 104 | (goto-char 1) 105 | (or (= (forward-line 1) 0) (insert "\n"))) 106 | (set-buffer obuf))) 107 | rtn)) 108 | 109 | ;;; ************************************************************************ 110 | ;;; Private functions 111 | ;;; ************************************************************************ 112 | 113 | (defun hbmap:dir-operate (pred dir-name form &optional no-save) 114 | "If PRED called on DIR-NAME is non-nil, evaluate FORM. 115 | Return t if PRED evaluation is successful and nil when not, except when 116 | hbmap is not readable or writable, in which case return a symbol indicating 117 | the error. Optional NO-SAVE disables saving of the map after operation." 118 | (save-excursion 119 | (let ((buf (unless (and (file-exists-p hbmap:dir-filename) 120 | (not (file-readable-p hbmap:dir-filename))) 121 | (find-file-noselect hbmap:dir-filename)))) 122 | (if buf 123 | (progn (set-buffer buf) 124 | (when (funcall pred dir-name) 125 | (setq buffer-read-only nil) 126 | (eval form) 127 | (cond (no-save 128 | t) 129 | ((file-writable-p (hypb:buffer-file-name)) 130 | (save-buffer) 131 | t) 132 | (t 'hbmap-not-writable)))) 133 | 'hbmap-not-readable)))) 134 | 135 | (provide 'hbmap) 136 | 137 | ;;; hbmap.el ends here 138 | -------------------------------------------------------------------------------- /hgnus.el: -------------------------------------------------------------------------------- 1 | ;;; hgnus.el --- GNU Hyperbole buttons in news reader/poster: GNUS -*- lexical-binding: t; -*- 2 | ;; 3 | ;; Author: Bob Weiner 4 | ;; 5 | ;; Orig-Date: 24-Dec-91 at 22:29:28 6 | ;; Last-Mod: 5-Feb-23 at 23:40:25 by Mats Lidell 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 1991-2022 Free Software Foundation, Inc. 11 | ;; See the "HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | 15 | ;;; Commentary: 16 | ;; 17 | ;; This only works with GNUS 3.15 or above, so be sure to check your 18 | ;; newsreader version {M-ESC gnus-version RET} before reporting any 19 | ;; problems. 20 | ;; 21 | ;; Automatically configured for use in "hyperbole.el". 22 | ;; If hsettings loading fails prior to initializing Hyperbole Gnus support, 23 | ;; 24 | ;; {M-x Gnus-init RET} 25 | ;; 26 | ;; will do it. 27 | ;; 28 | ;; 29 | ;; Have not yet overloaded 'news-reply-yank-original' 30 | ;; to yank and hide button data from news article buffer. 31 | ;; 32 | 33 | ;;; Code: 34 | ;;; ************************************************************************ 35 | ;;; Other required Elisp libraries 36 | ;;; ************************************************************************ 37 | 38 | (eval-and-compile (mapc #'require '(hload-path hmail hsmail hypb gnus-msg))) 39 | 40 | ;;; ************************************************************************ 41 | ;;; Public variables 42 | ;;; ************************************************************************ 43 | 44 | (setq hnews:composer 'news-reply-mode 45 | hnews:lister 'gnus-summary-mode 46 | hnews:reader 'gnus-article-mode) 47 | 48 | 49 | ;;; ************************************************************************ 50 | ;;; Public functions 51 | ;;; ************************************************************************ 52 | 53 | ;;;###autoload 54 | (defun Gnus-init () 55 | "Initialize Hyperbole support for Gnus Usenet news reading." 56 | (interactive) 57 | nil) 58 | 59 | (defun lnews:to () 60 | "Set current buffer to the Usenet news article summary listing buffer." 61 | (and (eq major-mode hnews:reader) (set-buffer gnus-summary-buffer))) 62 | 63 | (defun rnews:to () 64 | "Set current buffer to the Usenet news article reader buffer." 65 | (and (eq major-mode hnews:lister) (set-buffer gnus-article-buffer))) 66 | 67 | (defun rnews:summ-msg-to () 68 | "Displays news message associated with current summary header." 69 | (let ((article (gnus-summary-article-number))) 70 | (if (or (null gnus-current-article) 71 | (/= article gnus-current-article)) 72 | ;; Selected subject is different from current article's. 73 | (gnus-summary-display-article article)))) 74 | 75 | 76 | ;;; Overload this function from "rnewspost.el" for supercite compatibility 77 | ;;; only when supercite is in use. 78 | (if (hypb:supercite-p) 79 | (defun news-reply-yank-original (arg) 80 | "Supercite version of news-reply-yank-original. 81 | Insert the message being replied to in the reply buffer. Puts point 82 | before the mail headers and mark after body of the text. Calls 83 | mail-yank-original to actually yank the message into the buffer and 84 | cite text. 85 | 86 | If mail-yank-original is not overloaded by supercite, each nonblank 87 | line is indented ARG spaces (default 3). Just \\[universal-argument] 88 | as ARG means don't indent and don't delete any header fields." 89 | (interactive "P") 90 | (mail-yank-original arg) 91 | (exchange-point-and-mark) 92 | (run-hooks 'news-reply-header-hook))) 93 | 94 | ;;; ************************************************************************ 95 | ;;; Private variables 96 | ;;; ************************************************************************ 97 | ;;; 98 | (var:append 'gnus-Inews-article-hook '(widen)) 99 | ;;; 100 | ;;; Hide any Hyperbole button data and highlight buttons if possible 101 | ;;; in news article being read. 102 | (var:append 'gnus-article-prepare-hook 103 | (if (fboundp 'hproperty:but-create) 104 | '(hmail:msg-narrow hproperty:but-create) 105 | '(hmail:msg-narrow))) 106 | 107 | (if (fboundp 'hproperty:but-create) 108 | (var:append 'gnus-summary-prepare-hook '(hproperty:but-create))) 109 | 110 | ;; Try to setup comment addition as the first element of these hooks. 111 | ;; Called from 'news-post-news' if prev unsent article exists and user 112 | ;; says erase it. Add a comment on Hyperbole button support. 113 | (add-hook 'news-setup-hook #'smail:comment-add) 114 | ;; Called from 'news-post-news' if no prev unsent article exists. 115 | ;; Add a comment on Hyperbole button support. 116 | (add-hook 'news-reply-mode-hook #'smail:comment-add) 117 | 118 | (provide 'hgnus) 119 | 120 | ;;; hgnus.el ends here 121 | -------------------------------------------------------------------------------- /hhist.el: -------------------------------------------------------------------------------- 1 | ;;; hhist.el --- History of Hyperbole buttons selected -*- lexical-binding: t; -*- 2 | ;; 3 | ;; Author: Bob Weiner 4 | ;; 5 | ;; Orig-Date: 24-Apr-91 at 03:36:23 6 | ;; Last-Mod: 3-Oct-23 at 17:05:19 by Mats Lidell 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 1991-2022 Free Software Foundation, Inc. 11 | ;; See the "HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | ;; 15 | ;;; Commentary: 16 | ;; 17 | ;; This implements a last-in-first-out stack of traversed locations 18 | ;; for use as a locational history in Hyperbole. Each location stores 19 | ;; the frame and window locations of all buffers. When restoring a location, 20 | ;; if new frames are created after the location has been stored, they are 21 | ;; minimized, not deleted. Use the Emacs Buffer menu to return to them. 22 | ;; Frames which have been deleted are not restored. 23 | 24 | ;;; Code: 25 | ;;; ************************************************************************ 26 | ;;; Private variables 27 | ;;; ************************************************************************ 28 | 29 | (defconst *hhist* nil 30 | "List of previously visited Hyperbole button source locations. 31 | Car of list is most recent.") 32 | 33 | ;;; ************************************************************************ 34 | ;;; Public functions 35 | ;;; ************************************************************************ 36 | 37 | (defun hhist:add (elt) 38 | "Add ELT to hyper-history list. 39 | Do not add if the same as current or prior location (frame configuration). 40 | ELT must have been created via a call to `hhist:element' prior to 41 | changing the current frame configuration somehow." 42 | ;; Even though this next line looks useless, it cures a problem with 43 | ;; window buffer correspondences on startup, so don't remove it. 44 | (set-buffer (window-buffer (selected-window))) 45 | (when (not (frame-configuration-p elt)) 46 | (error "(hhist:add): 'elt' must be a frame configuration, not %s" elt)) 47 | (unless (or (equal elt (car *hhist*)) 48 | (equal elt (current-frame-configuration))) 49 | (setq *hhist* (cons elt *hhist*)))) 50 | 51 | (defun hhist:element () 52 | "Return a history element for current point location." 53 | (current-frame-configuration)) 54 | 55 | (defun hhist:pop (&optional arg) 56 | "Return to ARGth saved frame config and remove optional prefix ARG entries. 57 | The command is ignored with ARG < 1." 58 | (interactive "p") 59 | (setq arg (cond ((or (null arg) 60 | (and (listp arg) (not (integerp (car arg)))) 61 | (not (integerp arg))) 62 | 1) 63 | ((and (listp arg) (integerp (car arg))) 64 | (car arg)) 65 | ((listp arg) 1) 66 | (t arg))) 67 | (let ((prev-config)) 68 | (when *hhist* 69 | (when (< arg 1) 70 | (message "(hhist:pop): No previous location to which to return") 71 | (beep)) 72 | (while (and (> arg 0) *hhist*) 73 | (setq prev-config (car *hhist*) 74 | *hhist* (cdr *hhist*) 75 | arg (1- arg))) 76 | (when (frame-configuration-p prev-config) 77 | ;; Minify but keep any frames created after this frame configuration was saved. 78 | (set-frame-configuration prev-config t))))) 79 | 80 | (defun hhist:init () 81 | "Reset history list." 82 | (interactive) 83 | (setq *hhist* nil)) 84 | 85 | (provide 'hhist) 86 | 87 | ;;; hhist.el ends here 88 | -------------------------------------------------------------------------------- /hinit.el: -------------------------------------------------------------------------------- 1 | ;;; hinit.el --- Standard initializations for GNU Hyperbole -*- lexical-binding: t; -*- 2 | ;; 3 | ;; Author: Bob Weiner 4 | ;; 5 | ;; Orig-Date: 1-Oct-91 at 02:32:51 6 | ;; Last-Mod: 29-Oct-23 at 10:07:47 by Bob Weiner 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 1991-2023 Free Software Foundation, Inc. 11 | ;; See the "HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | 15 | ;;; Commentary: 16 | 17 | ;;; Code: 18 | ;;; ************************************************************************ 19 | ;;; Public variables 20 | ;;; ************************************************************************ 21 | 22 | (defvar hyperb:user-email nil 23 | "Email address for the current user. Set automatically by `hyperb:init'.") 24 | 25 | ;;; ************************************************************************ 26 | ;;; Other required Elisp libraries 27 | ;;; ************************************************************************ 28 | 29 | ;; Note: hibtypes must be loaded before hui-menu or klink defib priority 30 | ;; could be set improperly. 31 | (eval-and-compile (mapc #'require '(hvar hibtypes hui-menu hui-mouse hypb hui hui-mini hbmap))) 32 | 33 | ;;; ************************************************************************ 34 | ;;; Public functions 35 | ;;; ************************************************************************ 36 | 37 | (unless (fboundp 'br-in-browser) 38 | ;; Then the OO-Browser is not loaded, so we can never be within the 39 | ;; browser. Define this as a dummy function that always returns nil 40 | ;; until the OO-Browser is ever loaded. 41 | (defun br-in-browser () 42 | "Always return nil since the OO-Browser is not loaded." 43 | nil)) 44 | 45 | ;;;###autoload 46 | (defun hyperb:init-menubar () 47 | "Add a pulldown menu for Hyperbole after Emacs is initialized." 48 | (interactive) 49 | (unless (featurep 'infodock) 50 | ;; Initialize now since Emacs startup has finished. 51 | (if after-init-time (hyperbole-menubar-menu) 52 | ;; Defer initialization until after Emacs startup. This really is needed. 53 | (add-hook 'after-init-hook #'hyperbole-menubar-menu)) 54 | ;; Avoid returning the large Hyperbole menu. 55 | nil)) 56 | 57 | ;;; ************************************************************************ 58 | ;;; Menu Support Functions 59 | ;;; ************************************************************************ 60 | 61 | ;;;###autoload 62 | (defmacro hui-menu-remove (menu-sym &optional keymap) 63 | "Remove MENU-SYM from menubars generated by optional KEYMAP or the `global-map'." 64 | `(prog1 65 | (define-key (or ,keymap global-map) [menu-bar ,menu-sym] nil) 66 | ;; Force a menu-bar update. 67 | (force-mode-line-update))) 68 | 69 | ;;; ************************************************************************ 70 | ;;; Private functions 71 | ;;; ************************************************************************ 72 | 73 | (defun hyperb:check-dir-user () 74 | "Ensure `hbmap:dir-user' exists and is writable or signal an error." 75 | (if (or (null hbmap:dir-user) (not (stringp hbmap:dir-user)) 76 | (and (setq hbmap:dir-user (file-name-as-directory 77 | (expand-file-name hbmap:dir-user))) 78 | (file-directory-p hbmap:dir-user) 79 | (not (file-writable-p (directory-file-name hbmap:dir-user))))) 80 | (error 81 | "(hyperb:init): `hbmap:dir-user' must be a writable directory name")) 82 | (let ((hbmap:dir-user (directory-file-name hbmap:dir-user))) 83 | (or (file-directory-p hbmap:dir-user) ;; Exists and is writable. 84 | (let* ((parent-dir (file-name-directory 85 | (directory-file-name hbmap:dir-user)))) 86 | (cond 87 | ((not (file-directory-p parent-dir)) 88 | (error 89 | "(hyperb:init): `hbmap:dir-user' parent dir does not exist")) 90 | ((not (file-writable-p parent-dir)) 91 | (error 92 | "(hyperb:init): `hbmap:dir-user' parent directory not writable")) 93 | ((or (if (fboundp 'make-directory) 94 | (progn (make-directory hbmap:dir-user) t)) 95 | (hypb:call-process-p "mkdir" nil nil hbmap:dir-user)) 96 | (or (file-writable-p hbmap:dir-user) 97 | (or (progn (hypb:chmod '+ 700 hbmap:dir-user) 98 | (file-writable-p hbmap:dir-user)) 99 | (error "(hyperb:init): Can't write to 'hbmap:dir-user'")))) 100 | (t (error "(hyperb:init): `hbmap:dir-user' create failed")))))) 101 | t) 102 | 103 | (provide 'hinit) 104 | 105 | 106 | ;;; hinit.el ends here 107 | -------------------------------------------------------------------------------- /hmh.el: -------------------------------------------------------------------------------- 1 | ;;; hmh.el --- GNU Hyperbole buttons in mail reader: Mh -*- lexical-binding: t; -*- 2 | ;; 3 | ;; Author: Bob Weiner 4 | ;; 5 | ;; Orig-Date: 21-May-91 at 17:06:36 6 | ;; Last-Mod: 3-Oct-23 at 22:18:35 by Mats Lidell 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 1991-2022 Free Software Foundation, Inc. 11 | ;; See the "HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | 15 | ;;; Commentary: 16 | ;; 17 | ;; Automatically configured for use in "hsettings.el". 18 | ;; If hsettings loading fails prior to initializing Hyperbole Mh support, 19 | ;; 20 | ;; {M-x Mh-init RET} 21 | ;; 22 | ;; will do it. 23 | ;; 24 | ;; 25 | ;; Have not yet overloaded 'mh-yank-cur-msg' to yank and hide 26 | ;; button data from mail reader buffer. 27 | ;; Have not yet overloaded 'mh-insert-letter' to highlight buttons 28 | ;; and to merge its button data. 29 | ;; 30 | 31 | ;;; Code: 32 | ;;; ************************************************************************ 33 | ;;; Other required Elisp libraries 34 | ;;; ************************************************************************ 35 | 36 | (eval-and-compile (mapc #'require '(hload-path hmail mh-e))) 37 | (load "hsmail") 38 | 39 | ;;; ************************************************************************ 40 | ;;; Public declarations 41 | ;;; ************************************************************************ 42 | 43 | (declare-function hypb:window-list "hypb") 44 | 45 | ;;; ************************************************************************ 46 | ;;; Public functions 47 | ;;; ************************************************************************ 48 | 49 | ;;;###autoload 50 | (defun Mh-init () 51 | "Initialize Hyperbole support for Mh mail reading." 52 | (interactive) 53 | (setq hmail:composer 'mh-letter-mode 54 | hmail:lister 'mh-folder-mode 55 | hmail:modifier 'mh-letter-mode 56 | hmail:reader 'mh-show-mode) 57 | (var:append 'mh-show-hook '(hmail:msg-narrow Mh-hbut-highlight)) 58 | ;; 59 | ;; 60 | ;; Setup public abstract interface to Hyperbole defined mail 61 | ;; reader-specific functions used in "hmail.el". 62 | ;; 63 | (rmail:init) 64 | ;; 65 | ;; Setup private abstract interface to mail reader-specific functions 66 | ;; used in "hmail.el". 67 | ;; 68 | (defalias 'rmail:get-new 'mh-inc-folder) 69 | (defalias 'rmail:msg-forward 'mh-redistribute) 70 | (defalias 'rmail:summ-msg-to 'mh-goto-msg) 71 | (defalias 'rmail:summ-new 'mh-rescan-folder) 72 | (if (called-interactively-p 'interactive) 73 | (message "Hyperbole MH mail reader support initialized."))) 74 | 75 | (defun Mh-hbut-highlight () 76 | "Highlight any Hyperbole buttons in buffer for which display support exists." 77 | (if (fboundp 'hproperty:but-create) (hproperty:but-create))) 78 | 79 | (defun Mh-msg-hdrs-full (_toggled) 80 | "If TOGGLED is non-nil, toggle full/hidden headers, else show full headers. 81 | For now, a no-op.") 82 | 83 | (defun Mh-msg-narrow () 84 | "Narrow mail reader buffer to current message. 85 | This includes Hyperbole button data." 86 | (Mh-msg-widen)) 87 | 88 | (defun Mh-msg-next () (mh-next-undeleted-msg 1)) 89 | 90 | (defun Mh-msg-num () 91 | "Return number of mail message that point is within." 92 | (interactive) 93 | (mh-get-msg-num nil)) 94 | 95 | (defun Mh-msg-prev () (mh-previous-undeleted-msg 1)) 96 | 97 | (defun Mh-msg-to-p (_mail-msg-id mail-file) 98 | "Set current buffer to start of msg with MAIL-MSG-ID in MAIL-FILE. 99 | Returns t if successful, else nil." 100 | (if (not (file-readable-p mail-file)) 101 | nil 102 | (find-file mail-file) 103 | (hmail:msg-narrow) 104 | (goto-char 1) 105 | t)) 106 | 107 | (defun Mh-msg-widen () 108 | "Widens buffer to full current message including Hyperbole button data." 109 | (Mh-to) (widen)) 110 | 111 | (defun Mh-to () 112 | "Set current buffer to a mail reader buffer." 113 | (and (eq major-mode 'Mh-folder-mode) 114 | (set-buffer mh-show-buffer))) 115 | 116 | (defun Mh-Summ-delete () (mh-delete-msg (mh-get-msg-num t))) 117 | 118 | (defalias 'Mh-Summ-expunge 'mh-execute-commands) 119 | 120 | (defun Mh-Summ-goto () 121 | (let ((msg-num (mh-get-msg-num nil))) 122 | (mh-goto-msg msg-num nil t) 123 | (mh-show msg-num))) 124 | 125 | (defun Mh-Summ-to () 126 | "Set current buffer to a mail listing buffer." 127 | (let ((summ-buf)) 128 | (save-excursion 129 | (mapc (lambda (window) 130 | (if summ-buf 131 | nil 132 | (set-buffer (window-buffer window)) 133 | (if (eq major-mode 'Mh-folder-mode) 134 | (setq summ-buf (current-buffer))))) 135 | (hypb:window-list 'no-mini))) 136 | (if summ-buf (set-buffer summ-buf)))) 137 | 138 | (defun Mh-Summ-undelete-all () 139 | (message 140 | "(Mh-Summ-undelete-all: I don't think mh-e has an undelete operator.")) 141 | 142 | ;;; ************************************************************************ 143 | ;;; Private functions 144 | ;;; ************************************************************************ 145 | ;;; 146 | ;; Redefine version of this function from mh-e.el to run mh-show-hook at end. 147 | ;; This hook may already be run, depending on the version of mh-e you are 148 | ;; running, but running it twice shouldn't do any harm. Comment this out if 149 | ;; you know that your mh-e.el already runs the hook. 150 | ;; FIXME: `mh-show.el' has not changed much since Emacs-27 (which we require), 151 | ;; so we should not need such an advice, yet AFAICT `mh-display-msg' 152 | ;; doesn't run this hook, on `mh-show-msg' does. 153 | (advice-add 'mh-display-msg :after #'hmh--run-show-hook) 154 | (defun hmh--run-show-hook (&rest _) (run-hooks 'mh-show-hook)) 155 | 156 | ;; 157 | ;; Redefine version of 'mh-regenerate-headers' to highlight Hyperbole 158 | ;; buttons when possible. 159 | ;; 160 | ;; FIXME: Add a hook to MH-E so we don't need this advice. 161 | (advice-add 'mh-regenerate-headers :after #'hmh--highlight-buttons) 162 | (defun hmh--highlight-buttons (&rest _) 163 | (if (fboundp 'hproperty:but-create) (hproperty:but-create))) 164 | 165 | ;;; 166 | ;;; Set 'mh-send-letter' hook to widen to include button data before sending. 167 | ;;; 168 | (var:append 'mh-before-send-letter-hook '(widen)) 169 | 170 | ;;; ************************************************************************ 171 | ;;; Private variables 172 | ;;; ************************************************************************ 173 | 174 | (provide 'hmh) 175 | 176 | 177 | ;;; hmh.el ends here 178 | -------------------------------------------------------------------------------- /hsys-ert.el: -------------------------------------------------------------------------------- 1 | ;;; hsys-ert.el --- Hyperbole support for jumping to ert 'should' source lines -*- lexical-binding: t -*- 2 | ;; 3 | ;; Author: Bob Weiner 4 | ;; 5 | ;; Orig-Date: 19-Jan-25 6 | ;; Last-Mod: 22-Feb-25 at 12:20:29 by Bob Weiner 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 2025 Free Software Foundation, Inc. 11 | ;; See the "HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | 15 | ;;; Commentary: 16 | ;; 17 | ;; ERT is the Emacs Regression Test framework in "ert.el". Hyperbole uses 18 | ;; it for all of its regression testing as well. 19 | ;; 20 | ;; Sometimes when building Emacs Lisp tests with the ERT package, multiple 21 | ;; tests are added to a single test fixture/function. Each subtest 22 | ;; has its own `should'-type clause. But if one of these subtests fails, 23 | ;; ERT shows you the test name and the should clause in its results buffer 24 | ;; but if there are 12 subtests, it is difficult to match the displayed 25 | ;; should clause to the source line that ran it. 26 | ;; 27 | ;; The `ert-should' implicit button type defined herein solves this problem. 28 | ;; Hyperbole loads this and then a press of the Action Key within an ert 29 | ;; results buffer (or another buffer to which the results have been copied) 30 | ;; produces the following: 31 | ;; 32 | ;; - If on the first line of the result with the test name, jump to the 33 | ;; test definition. 34 | ;; 35 | ;; - If on a highlighted button, activate the button. 36 | ;; 37 | ;; - Otherwise if not at the end of a line and within a failed test result, 38 | ;; find the `should' clause and go to the matching line within the test 39 | ;; source code. An easy way to use it is to put point at the beginning 40 | ;; of a line other than the first within an ert result and press the 41 | ;; Action Key. 42 | 43 | ;;; Code: 44 | 45 | ;;; ************************************************************************ 46 | ;;; Other required Elisp libraries 47 | ;;; ************************************************************************ 48 | 49 | (require 'hbut) ;; For defib 50 | (require 'hmouse-tag) ;; For smart-lisp 51 | 52 | ;;; ************************************************************************ 53 | ;;; Implicit button types 54 | ;;; ************************************************************************ 55 | 56 | (defib ert-should () 57 | "Jump to the source code definition of a should expr from an ert test failure. 58 | If on the first line of a failure, jump to the source definition of the 59 | associated test." 60 | (when (or (and (derived-mode-p 'ert-results-mode) 61 | (save-excursion 62 | (forward-line 0) 63 | (or (search-backward "(ert-test-failed\n" nil t) 64 | (search-forward "(ert-test-failed\n" nil t)))) 65 | ;; In any other mode, consider only the current line 66 | (save-excursion 67 | (forward-line 0) 68 | (search-forward "(ert-test-failed" (line-end-position) t))) 69 | (catch 'exit 70 | (save-excursion 71 | (save-restriction 72 | (forward-line 0) 73 | (cond ((looking-at "\\`\\|^[AFPS] ") 74 | ;; On a result line with a test name, jump to the test 75 | (goto-char (match-end 0)) 76 | ;; Use the test definition name as the ibut label 77 | (ibut:label-set (buffer-substring-no-properties 78 | (+ 2 (line-beginning-position)) 79 | (line-end-position)) 80 | (+ 2 (line-beginning-position)) 81 | (line-end-position)) 82 | (let ((major-mode 'emacs-lisp-mode)) 83 | (if (button-at (point)) 84 | ;; jump to source buffer 85 | (push-button) 86 | (throw 'exit (hact 'smart-lisp))))) 87 | ((looking-at "\\s-*(ert-test-failed\\s-") 88 | (when (re-search-forward "^\\s-+(\\((should\\)\\(-\\|\\s-\\)" nil t) 89 | (goto-char (match-beginning 1)))) 90 | ((looking-at "\\s-*(\\((should\\)\\(-\\|\\s-\\)") 91 | (goto-char (match-beginning 1))) 92 | ((re-search-backward "\\`\\|^[AFPS] " nil t) 93 | (let ((start (point))) 94 | (goto-char (1+ (point))) 95 | (when (re-search-forward "^[AFPS] \\|\\'" nil t) 96 | (goto-char (1- (match-beginning 0))) 97 | (narrow-to-region start (point)) 98 | (goto-char start) 99 | (when (re-search-forward "^\\s-+(\\((should\\)\\(-\\|\\s-\\)" nil t) 100 | (goto-char (match-beginning 1))))))) 101 | (when (looking-at "(should\\(-\\|\\s-\\)") 102 | (let ((should-regexp (regexp-quote (thing-at-point 'sexp)))) 103 | (setq should-regexp (replace-regexp-in-string 104 | "[ \t\n\r\f]+" "\\s-+" (string-trim should-regexp) 105 | t t)) 106 | ;; follow the function link to the source file of the function 107 | (when (re-search-backward "^[AFPS] " nil t) 108 | (goto-char (match-end 0)) 109 | (let ((major-mode 'emacs-lisp-mode)) 110 | (if (button-at (point)) 111 | ;; jump to source buffer 112 | (push-button) 113 | (smart-lisp)) 114 | ;; re-search-forward for should-regexp 115 | (when (re-search-forward should-regexp nil t) 116 | (goto-char (match-beginning 0)) 117 | (ibut:label-set "(should" (point) (+ (point) 7)) 118 | (hact 'identity t))))))))))) 119 | 120 | (provide 'hsys-ert) 121 | 122 | ;;; hsys-ert.el ends here 123 | -------------------------------------------------------------------------------- /hsys-org-roam.el: -------------------------------------------------------------------------------- 1 | ;;; hsys-org.el --- GNU Hyperbole support functions for Org Roam -*- lexical-binding: t; -*- 2 | ;; 3 | ;; Author: Bob Weiner 4 | ;; 5 | ;; Orig-Date: 26-Feb-23 at 11:20:15 by Bob Weiner 6 | ;; Last-Mod: 5-Jan-25 at 12:06:23 by Bob Weiner 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 2023-2024 Free Software Foundation, Inc. 11 | ;; See the "HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | 15 | ;;; Commentary: 16 | ;; 17 | ;; The autoloaded function, `hsys-org-roam-consult-grep', uses 18 | ;; consult-grep to do a full-text search over notes included 19 | ;; into the user's Org Roam database. 20 | ;; 21 | ;; Use `org-roam-migrate-wizard' to import any Org note files and 22 | ;; assign them UUIDs required for indexing by Org Roam. 23 | 24 | ;;; Code: 25 | ;;; ************************************************************************ 26 | ;;; Other required Elisp libraries 27 | ;;; ************************************************************************ 28 | 29 | (require 'hypb) 30 | (require 'package) 31 | 32 | ;;; ************************************************************************ 33 | ;;; Public declarations 34 | ;;; ************************************************************************ 35 | 36 | (defvar consult-org-roam-grep-func) 37 | (defvar hsys-org-at-tags-p) 38 | (defvar org-agenda-buffer-tmp-name) 39 | (defvar org-agenda-files) 40 | (defvar org-roam-directory) 41 | (declare-function hsys-org-at-tags-p "hsys-org") 42 | (declare-function hypb:require-package "hypb") 43 | (declare-function org-roam-db-autosync-mode "ext:org-roam") 44 | 45 | ;;; ************************************************************************ 46 | ;;; Public functions 47 | ;;; ************************************************************************ 48 | 49 | ;;;###autoload 50 | (defun hsys-org-roam-consult-grep () 51 | "Prompt for search terms and run consult grep over `org-roam-directory'. 52 | Actual grep function used is given by the variable, 53 | `consult-org-roam-grep-func'." 54 | (interactive) 55 | (hypb:require-package 'consult-org-roam) 56 | (let ((grep-func (when (and (boundp 'consult-org-roam-grep-func) 57 | (fboundp consult-org-roam-grep-func)) 58 | consult-org-roam-grep-func))) 59 | (if grep-func 60 | (funcall grep-func org-roam-directory) 61 | (error "(hsys-org-roam-consult-grep): `%s' is an invalid function" 62 | consult-org-roam-grep-func)))) 63 | 64 | (defun hsys-org-roam-directory-at-tags-p (&optional at-tag-flag) 65 | "Return non-nil if point is in an `org-roam-directory' buffer and at Org tags." 66 | (and (featurep 'org-roam) 67 | (or at-tag-flag (hsys-org-at-tags-p)) 68 | (and (hypb:buffer-file-name) 69 | (string-prefix-p (expand-file-name org-roam-directory) 70 | (hypb:buffer-file-name))))) 71 | 72 | ;;;###autoload 73 | (defun hsys-org-roam-tags-view (&optional todo-only match view-buffer-name) 74 | "Prompt for colon-separated Org Roam tags and display matching headlines. 75 | With optional prefix arg TODO-ONLY, limit matches to Org Roam 76 | todo items only. With optional MATCH, an Org tags match selector 77 | string, e.g. \":tag1:tag2:tag3:\", match to sections that contain 78 | or inherit all of these tags, regardless of tag order. With 79 | optional VIEW-BUFFER-NAME, use that rather than the default, 80 | \"*Org Roam Tags*\"." 81 | (interactive "P") 82 | (require 'org-agenda) 83 | (hypb:require-package 'org-roam) 84 | (let* ((org-agenda-files (list org-roam-directory)) 85 | (org-agenda-buffer-name (or view-buffer-name "*Org Roam Tags*")) 86 | ;; `org-tags-view' is mis-written to require setting this next 87 | ;; tmp-name or it will not properly name the displayed buffer. 88 | (org-agenda-buffer-tmp-name org-agenda-buffer-name)) 89 | ;; This prompts for the tags to match and uses `org-agenda-files'. 90 | (org-tags-view todo-only match) 91 | (when (equal (buffer-name) org-agenda-buffer-name) 92 | ;; Set up {C-u r} redo cmd 93 | (let (buffer-read-only) 94 | (put-text-property (point-min) (point-max) 'org-redo-cmd 95 | `(hsys-org-roam-tags-view 96 | ,todo-only 97 | nil 98 | ,org-agenda-buffer-name))) 99 | (forward-line 2)))) 100 | 101 | (provide 'hsys-org-roam) 102 | 103 | ;;; hsys-org-roam.el ends here 104 | -------------------------------------------------------------------------------- /hsys-xref.el: -------------------------------------------------------------------------------- 1 | ;;; hsys-xref.el --- GNU Hyperbole support functions for "xref.el" -*- lexical-binding: t; -*- 2 | ;; 3 | ;; Author: Bob Weiner 4 | ;; 5 | ;; Orig-Date: 24-Aug-91 6 | ;; Last-Mod: 14-Apr-25 at 15:51:27 by Mats Lidell 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 1991-2024 Free Software Foundation, Inc. 11 | ;; See the "HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | 15 | ;;; Commentary: 16 | 17 | ;;; Code: 18 | 19 | ;;; ************************************************************************ 20 | ;;; Requirements 21 | ;;; ************************************************************************ 22 | 23 | (require 'xref) 24 | 25 | ;;; ************************************************************************ 26 | ;;; Public declarations 27 | ;;; ************************************************************************ 28 | 29 | (declare-function smart-emacs-lisp-mode-p "hmouse-tag") 30 | (declare-function hpath:at-p "hpath") 31 | 32 | ;;; ************************************************************************ 33 | ;;; Public functions 34 | ;;; ************************************************************************ 35 | 36 | (defun hsys-xref-definitions (identifier) 37 | "Return a list of all definitions of string IDENTIFIER." 38 | (let* ((elisp-flag (smart-emacs-lisp-mode-p t)) 39 | (xref-backend (or (and elisp-flag 40 | (fboundp 'ert-test-boundp) 41 | (ert-test-boundp (intern-soft identifier)) 42 | (boundp 'xref-etags-mode) 43 | 'etags) 44 | (xref-find-backend))) 45 | (xref-items (xref-backend-definitions xref-backend identifier))) 46 | xref-items)) 47 | 48 | (defun hsys-xref-definition (identifier) 49 | "Return the first definition of string IDENTIFIER." 50 | (car (hsys-xref-definitions identifier))) 51 | 52 | (defun hsys-xref-identifier-at-point () 53 | "Return nil if xref returns a pathname as an identifier." 54 | (unless (hpath:at-p nil t) 55 | (xref-backend-identifier-at-point (xref-find-backend)))) 56 | 57 | (defun hsys-xref-item-buffer (item) 58 | "Return the buffer in which xref ITEM is defined." 59 | (marker-buffer (save-excursion (xref-location-marker (xref-item-location item))))) 60 | 61 | (defun hsys-xref-item-position (item) 62 | "Return the buffer position where xref ITEM is defined." 63 | (marker-position (save-excursion (xref-location-marker (xref-item-location item))))) 64 | 65 | ;;; ************************************************************************ 66 | ;;; Private functions 67 | ;;; ************************************************************************ 68 | 69 | (defun xref--item-at-point () 70 | "Fix next xref function to handle when called at beginning of buffer." 71 | (get-text-property 72 | (max (point-min) (if (eolp) (1- (point)) (point))) 73 | 'xref-item)) 74 | 75 | (defalias 'hsys-xref-item-at-point #'xref--item-at-point) 76 | 77 | (provide 'hsys-xref) 78 | 79 | ;;; hsys-xref.el ends here 80 | -------------------------------------------------------------------------------- /hui-dired-sidebar.el: -------------------------------------------------------------------------------- 1 | ;;; hui-dired-sidebar.el --- Hyperbole Smart Key support for dired sidebar -*- lexical-binding: t; -*- 2 | ;; 3 | ;; Author: Mats Lidell 4 | ;; 5 | ;; Orig-Date: 25-Jul-20 6 | ;; Last-Mod: 19-Jan-24 at 12:13:30 by Mats Lidell 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 2020-2021 Free Software Foundation, Inc. See the 11 | ;; "HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | 15 | ;;; Commentary: 16 | 17 | ;;; Code: 18 | ;;; ************************************************************************ 19 | ;;; Other required Elisp libraries 20 | ;;; ************************************************************************ 21 | 22 | (eval-and-compile (require 'dired-sidebar nil t)) 23 | 24 | ;;; ************************************************************************ 25 | ;;; Public declarations 26 | ;;; ************************************************************************ 27 | 28 | (defvar dired-sidebar-cycle-subtree-on-click) 29 | 30 | (defvar assist-flag) ; "hmouse-drv.el" 31 | (defvar action-key-eol-function) ; "hmouse-drv.el" 32 | (defvar assist-key-eol-function) ; "hmouse-drv.el" 33 | 34 | (declare-function dired-sidebar-toggle-sidebar "ext:dired-sidebar") 35 | 36 | (declare-function dired-get-file-for-visit "dired") 37 | (declare-function hact "hact") 38 | (declare-function first-line-p "hui-mouse") 39 | (declare-function last-line-p "hui-mouse") 40 | 41 | ;;; ************************************************************************ 42 | ;;; smart-dired-sidebar functions 43 | ;;; ************************************************************************ 44 | 45 | ;;;###autoload 46 | (defun smart-dired-sidebar () 47 | "Use a single key or mouse key to manipulate directory entries. 48 | 49 | Invoked via a key press when in dired-sidebar-mode. It assumes 50 | that its caller has already checked that the key was pressed in 51 | an appropriate buffer and has moved the cursor there. 52 | 53 | If key is pressed: 54 | (1) within an entry line, the item is displayed for editing, 55 | normally in another window, or if it is a directory and 56 | `dired-sidebar-cycle-subtree-on-click' is t it will expand 57 | and collapse the entry 58 | (2) at the end of an entry line: invoke `action-key-eol-function', 59 | typically to scroll up proportionally, if an Action Key press; invoke 60 | `assist-key-eol-function', typically to scroll down proportionally, 61 | if an Asisst Key press; 62 | (3) on the first line of the buffer (other than the end of line), 63 | Dired is run on the current directory of this dired-sidebar; 64 | (4) at the end of the first or last line of the buffer, 65 | this dired-sidebar invocation is hidden." 66 | 67 | (interactive) 68 | (cond ((first-line-p) 69 | (if (eolp) 70 | (dired-sidebar-toggle-sidebar) 71 | (hact 'link-to-directory default-directory))) 72 | ((and (last-line-p) (eolp)) 73 | (dired-sidebar-toggle-sidebar)) 74 | ((eolp) 75 | (funcall (if assist-flag assist-key-eol-function action-key-eol-function))) 76 | (t (let ((file (dired-get-file-for-visit))) 77 | (if (and dired-sidebar-cycle-subtree-on-click 78 | (file-directory-p file) 79 | (not (string-suffix-p "." file))) 80 | (hact 'dired-sidebar-subtree-toggle) 81 | (hact 'dired-sidebar-find-file file)))))) 82 | 83 | (provide 'hui-dired-sidebar) 84 | ;;; hui-dired-sidebar.el ends here 85 | -------------------------------------------------------------------------------- /hui-register.el: -------------------------------------------------------------------------------- 1 | ;;; hui-register.el --- register support for Hyperbole -*- lexical-binding: t; -*- 2 | ;; 3 | ;; Author: Mats Lidell 4 | ;; 5 | ;; Orig-Date: 6-Oct-91 at 03:42:38 6 | ;; Last-Mod: 4-Nov-24 at 00:36:58 by Mats Lidell 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 1991-2022 Free Software Foundation, Inc. 11 | ;; See the "HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | 15 | ;;; Code: 16 | 17 | ;;; Commentary: 18 | ;; 19 | ;; Implements a struct for ebut and ibut, a content type of a 20 | ;; register. See "(Emacs)Registers" 21 | ;; 22 | 23 | (eval-when-compile (require 'cl-lib)) 24 | (require 'hload-path) 25 | (require 'hbut) 26 | 27 | ;;; ************************************************************************ 28 | ;;; Public functions 29 | ;;; ************************************************************************ 30 | 31 | (cl-defstruct hui-register-but 32 | "Button register struct." 33 | label file mpos link) 34 | 35 | ;;;###autoload 36 | (defun hui-register-struct-at-point () 37 | "Make a Hyperbole link to button register struct for button at point." 38 | (let* ((ebut-label (ebut:label-p)) 39 | (ibut-label (ibut:label-p)) 40 | (label (or ebut-label ibut-label))) 41 | (unless label 42 | (hypb:error "Point must be at a Hyperbole button")) 43 | (make-hui-register-but 44 | :label label 45 | :file (hypb:buffer-file-name) 46 | :mpos (point-marker) 47 | :link (if ebut-label 'link-to-ebut 'link-to-ibut)))) 48 | 49 | ;;; ************************************************************************ 50 | ;;; Private functions 51 | ;;; ************************************************************************ 52 | 53 | (cl-defmethod register-val-jump-to ((val hui-register-but) _arg) 54 | "Move point to location for Hyperbole button stored in VAL." 55 | (let ((buf (marker-buffer (hui-register-but-mpos val))) 56 | (pos (marker-position (hui-register-but-mpos val)))) 57 | (unless buf 58 | (user-error "That Hyperbole button's buffer no longer exists")) 59 | (switch-to-buffer buf) 60 | (goto-char pos))) 61 | 62 | (cl-defmethod register-val-describe ((val hui-register-but) _verbose) 63 | "Print description of Hyperbole button register value VAL to `standard-output'." 64 | (princ "Hyperbole button\n ") 65 | (princ (format "%s in file %s\n" 66 | (hui-register-but-label val) 67 | (hui-register-but-file val)))) 68 | 69 | (cl-defmethod register-val-insert ((val hui-register-but)) 70 | "Insert an ebut linking to the register button stored in VAL." 71 | (ebut:program (hui-register-but-label val) 72 | (hui-register-but-link val) 73 | (hui-register-but-label val) 74 | (hui-register-but-file val))) 75 | 76 | (provide 'hui-register) 77 | ;;; hui-register.el ends here 78 | -------------------------------------------------------------------------------- /hui-treemacs.el: -------------------------------------------------------------------------------- 1 | ;;; hui-treemacs.el --- GNU Hyperbole Smart Key support for the Treemacs file manager package -*- lexical-binding: t; -*- 2 | ;; 3 | ;; Author: Bob Weiner 4 | ;; 5 | ;; Orig-Date: 19-Nov-17 6 | ;; Last-Mod: 13-Nov-24 at 13:09:22 by Mats Lidell 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 2017-2024 Free Software Foundation, Inc. 11 | ;; See the "HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | 15 | ;;; Commentary: 16 | ;; Ignore loading of this file unless the Treemacs package v2 or 17 | ;; greater has been installed. 18 | 19 | ;;; Code: 20 | ;;; ************************************************************************ 21 | ;;; Other required Elisp libraries 22 | ;;; ************************************************************************ 23 | 24 | (require 'package) 25 | (require 'seq) 26 | 27 | (or (require 'treemacs nil t) 28 | (and (package-installed-p 'treemacs) 29 | (package-activate 'treemacs)) 30 | (hypb:require-package 'treemacs)) 31 | 32 | (defvar treemacs-version) 33 | 34 | (unless (string-greaterp treemacs-version "v2") 35 | (error "(hui-treemacs): Hyperbole requires Treemacs package version 2.0 or greater, not %s" treemacs-version)) 36 | 37 | ;;; ************************************************************************ 38 | ;;; Public declarations 39 | ;;; ************************************************************************ 40 | (defvar action-key-depress-window) ; "hmouse-drv.el" 41 | (defvar action-key-eol-function) ; "hmouse-drv.el" 42 | (defvar assist-flag) ; "hmouse-drv.el" 43 | (defvar assist-key-eol-function) ; "hmouse-drv.el" 44 | (defvar aw-ignored-buffers) 45 | 46 | (declare-function first-line-p "hui-mouse") 47 | (declare-function hact "hact") 48 | (declare-function hypb:require-package "hypb") 49 | (declare-function last-line-p "hui-mouse") 50 | (declare-function package-activate "package") 51 | (declare-function treemacs "ext:treemacs") 52 | (declare-function treemacs-add-and-display-current-project-exclusively "ext:treemacs") 53 | (declare-function treemacs-current-button "ext:treemacs-core-utils") 54 | (declare-function treemacs-current-visibility "ext:treemacs-scope") 55 | (declare-function treemacs-display-current-project-exclusively "ext:treemacs") 56 | (declare-function treemacs-get-local-window "ext:treemacs-scope") 57 | (declare-function treemacs-is-treemacs-window? "ext:treemacs-core-utils") 58 | (declare-function treemacs-node-buffer-and-position "ext:treemacs-mouse-interface") 59 | (declare-function treemacs-quit "ext:treemacs-interface") 60 | (declare-function treemacs-toggle-node "ext:treemacs-interface") 61 | 62 | ;;; ************************************************************************ 63 | ;;; smart-treemacs functions 64 | ;;; ************************************************************************ 65 | 66 | ;; Want to be able to select Treemacs window with ace-window. 67 | ;; This also averts window labeling problems with ace-window. 68 | (eval-after-load "ace-window" 69 | '(setq aw-ignored-buffers (delq 'treemacs-mode aw-ignored-buffers))) 70 | 71 | (unless (fboundp 'treemacs-quit) 72 | (fset 'treemacs-quit #'bury-buffer)) 73 | 74 | ;;;###autoload 75 | (defun smart-treemacs-edit (&optional dir) 76 | "Use `treemacs' to edit optional DIR or the `default-directory'." 77 | (let ((default-directory (if (stringp dir) dir default-directory))) 78 | (cond ((fboundp #'treemacs-add-and-display-current-project-exclusively) 79 | (treemacs-add-and-display-current-project-exclusively)) 80 | ;; Older obsoleted function 81 | ((fboundp #'treemacs-display-current-project-exclusively) 82 | (treemacs-display-current-project-exclusively)) 83 | (t (treemacs))))) 84 | 85 | (defun smart-treemacs-quit (&optional arg) 86 | "Quit treemacs visible in current frame with `bury-buffer'. 87 | With a prefix ARG call `treemacs-kill-buffer' instead." 88 | (interactive "P") 89 | (when (eq (treemacs-current-visibility) 'visible) 90 | (with-selected-window (treemacs-get-local-window) 91 | (treemacs-quit arg)))) 92 | 93 | ;;;###autoload 94 | (defun smart-treemacs () 95 | "Use a single key or mouse key to manipulate directory entries. 96 | 97 | Invoked via a key press when in treemacs-mode. It assumes that its 98 | caller has already checked that the key was pressed in an appropriate buffer 99 | and has moved the cursor there. 100 | 101 | If key is pressed: 102 | (1) on or to the left of an entry icon, run the treemacs TAB command 103 | to expand or collapse the entry; 104 | (2) elsewhere within an entry line, display the item, which may be a 105 | directory, for editing, normally in another window; 106 | (3) at the end of an entry line: if an Action Key press, invoke 107 | `action-key-eol-function', typically to scroll up proportionally; 108 | if an Asisst Key press, invoke `assist-key-eol-function', typically 109 | to scroll down proportionally; 110 | (4) at the end of the first or last line of the buffer, quit this 111 | Treemacs invocation." 112 | 113 | (interactive) 114 | (cond ((and (eolp) (or (first-line-p) (last-line-p))) 115 | (hact 'smart-treemacs-quit)) 116 | ((eolp) 117 | (hact 'funcall (if assist-flag assist-key-eol-function action-key-eol-function))) 118 | (t (if (and (treemacs-current-button) 119 | (= (point) (- (button-start (treemacs-current-button)) 2))) 120 | ;; Before or on the entry's icon 121 | (hact 'treemacs-TAB-action current-prefix-arg) 122 | ;; On the entry, handles dirs, files and tag entries 123 | (hact 'treemacs-RET-action current-prefix-arg))))) 124 | 125 | ;;;###autoload 126 | (defun smart-treemacs-modeline () 127 | "Toggle display of Treemacs from Smart Action Key click on a modeline. 128 | 129 | When pressed on the Treemacs buffer modeline or Treemacs is displaying 130 | the default directory of the buffer modeline clicked upon, then 131 | quit/hide the Treemacs window. Otherwise, display the Treemacs window 132 | with the default directory of the buffer modeline clicked upon. 133 | 134 | Suitable for use as a value of `action-key-modeline-buffer-id-function'." 135 | (cond 136 | ;; Clicked on Treemacs buffer id 137 | ((if action-key-depress-window 138 | (treemacs-is-treemacs-window? action-key-depress-window) 139 | (hact 'string-match " Treemacs " (format-mode-line mode-line-format))) 140 | ;; Quit/hide treemacs. 141 | (hact 'treemacs-quit)) 142 | ;; 143 | ;; Treemacs is visible and displaying the same dir as 144 | ;; the default dir of the clicked on modeline. 145 | ((and (eq (treemacs-current-visibility) 'visible) 146 | (string-equal (expand-file-name default-directory) 147 | (with-selected-window (treemacs-get-local-window) 148 | (save-excursion 149 | (goto-char (point-min)) 150 | default-directory)))) 151 | ;; Quit/hide treemacs. 152 | (hact 'smart-treemacs-quit)) 153 | ;; 154 | ;; Otherwise, invoke treemacs on the default dir of the clicked on modeline. 155 | (t (hact 'smart-treemacs-edit)))) 156 | 157 | (provide 'hui-treemacs) 158 | ;;; hui-treemacs.el ends here 159 | 160 | -------------------------------------------------------------------------------- /hvar.el: -------------------------------------------------------------------------------- 1 | ;;; hvar.el --- Variable manipulation routines for GNU Hyperbole -*- lexical-binding: t; -*- 2 | ;; 3 | ;; Author: Bob Weiner 4 | ;; 5 | ;; Orig-Date: 1-Oct-91 at 14:00:24 6 | ;; Last-Mod: 29-May-24 at 01:08:47 by Bob Weiner 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 1991-2022 Free Software Foundation, Inc. 11 | ;; See the "HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | 15 | ;;; Commentary: 16 | 17 | ;;; Code: 18 | ;;; ************************************************************************ 19 | ;;; Other required Elisp libraries 20 | ;;; ************************************************************************ 21 | 22 | (require 'set) 23 | 24 | ;;; ************************************************************************ 25 | ;;; Forward declarations 26 | ;;; ************************************************************************ 27 | 28 | (defvar inhibit-hyperbole-messaging) ; ; Defined in `hsettings' required below 29 | 30 | ;;; ************************************************************************ 31 | ;;; Private variables 32 | ;;; ************************************************************************ 33 | 34 | (defvar var::append-list nil 35 | "List of (VAR-SYMBOL . APPENDED-LIST) elements saved from this Emacs session.") 36 | 37 | ;;; ************************************************************************ 38 | ;;; Public functions 39 | ;;; ************************************************************************ 40 | 41 | ;;;###autoload 42 | (defun var:add-and-run-hook (hook hook-function) 43 | "Add to mode HOOK the HOOK-FUNCTION; call it in matching major-mode buffers. 44 | HOOK is a symbol whose name begins with a major-mode name and ends with 45 | \"-hook\"." 46 | (add-hook hook hook-function) 47 | (let* ((hook-name (symbol-name hook)) 48 | (mode (when (string-match "-hooks?\\'" hook-name) 49 | (intern (substring hook-name 0 (match-beginning 0)))))) 50 | (when mode (var:run-hook-in-matching-buffers mode hook-function)))) 51 | 52 | (defun var:append-all () 53 | "Add back all hook values previously added by var:append in this Emacs session. 54 | The ones that were removed by `var:remove-all' at some point." 55 | (mapc (lambda (elt) (var:append (car elt) (cdr elt))) 56 | var::append-list) 57 | var::append-list) 58 | 59 | ;;;###autoload 60 | (defun var:append (var-symbol list-to-add) 61 | "Append to value held by VAR-SYMBOL, LIST-TO-ADD. Return new value. 62 | If VAR-SYMBOL is unbound, it is set to LIST-TO-ADD. 63 | Use to append to hook variables. Store all values for later removal. 64 | Do nothing when `inhibit-hyperbole-messaging' is non-nil." 65 | (unless (symbolp var-symbol) 66 | (error "(var:append): First argument, `%s', must be a symbol (not a string)" var-symbol)) 67 | (unless (and list-to-add (listp list-to-add)) 68 | (error "(var:append): Second argument, `%s', must be a non-empty list" list-to-add)) 69 | (unless inhibit-hyperbole-messaging 70 | (let ((val) result) 71 | (setq result 72 | (if (and (boundp var-symbol) 73 | (setq val (symbol-value var-symbol)) 74 | (or (when (symbolp val) 75 | (setq val (cons val nil))) 76 | (listp val))) 77 | (progn (when (functionp val) 78 | (setq val (list val))) 79 | (set var-symbol (set:union val list-to-add))) 80 | (set var-symbol list-to-add))) 81 | (add-to-list 'var::append-list (cons var-symbol result)) 82 | (symbol-value var-symbol)))) 83 | 84 | (defun var:remove (var-symbol list-to-remove) 85 | "Remove from VAR-SYMBOL the functions in LIST-TO-REMOVE. 86 | Use to remove from hook variables." 87 | (unless (symbolp var-symbol) 88 | (error "(var:remove): First argument, `%s', must be a symbol (not a string)" var-symbol)) 89 | (unless (and list-to-remove (listp list-to-remove)) 90 | (error "(var:remove): Second argument, `%s', must be a non-empty list" list-to-remove)) 91 | (when (eq (car list-to-remove) 'lambda) 92 | (setq list-to-remove (list list-to-remove))) 93 | (mapc (lambda (func) (remove-hook var-symbol func)) 94 | list-to-remove) 95 | (setq var::append-list (delete (cons var-symbol list-to-remove) var::append-list)) 96 | (symbol-value var-symbol)) 97 | 98 | (defun var:remove-all () 99 | "Remove all hook values added by `var:append' from their hook variables. 100 | Affects only those hook values added by `var:append' in this Emacs session. 101 | Keep a copy of these values for future re-use; see `var:append-all'." 102 | (mapc (lambda (elt) (var:remove (car elt) (cdr elt))) 103 | var::append-list) 104 | var::append-list) 105 | 106 | (defun var:run-hook-in-matching-buffers (mode hook-function) 107 | "Within all buffers with a given major MODE, call HOOK-FUNCTION. 108 | This is used after a hook is changed to affect buffers that 109 | existed before the change was made." 110 | (mapc (lambda (buf) (with-current-buffer buf (funcall hook-function))) 111 | (delq nil (mapcar (lambda (buf) (when (eq (buffer-local-value 'major-mode buf) mode) 112 | buf)) 113 | (buffer-list))))) 114 | 115 | ;;; ************************************************************************ 116 | ;;; Private variables 117 | ;;; ************************************************************************ 118 | 119 | (defvar var::append-list nil 120 | "List of (var-symbol . appended-list) elements saved from this Emacs session.") 121 | 122 | (provide 'hvar) 123 | 124 | 125 | ;; `hsettings' and `hvar' have a cyclic dependency; require this after providing 'hvar 126 | ;; to avoid an infinite loop. 127 | (require 'hsettings) 128 | 129 | ;;; hvar.el ends here 130 | -------------------------------------------------------------------------------- /hypb-ert.el: -------------------------------------------------------------------------------- 1 | ;;; hypb-ert.el --- Hyperbole test runner action button types -*- lexical-binding: t; -*- 2 | 3 | ;; Author: Mats Lidell and Bob Weiner 4 | ;; 5 | ;; Orig-Date: 31-Mar-21 at 21:11:00 6 | ;; Last-Mod: 20-Jan-24 at 15:41:52 by Mats Lidell 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 2021-2024 Free Software Foundation, Inc. 11 | ;; See the "HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | 15 | ;;; Commentary: 16 | 17 | ;; Creates two action link implicit button types for running any Hyperbole test 18 | ;; defined in "${hyperb:dir}/test/". 19 | ;; 20 | ;; Examples: 21 | ;; Run the test named hbut-defal-url: 22 | ;; 23 | ;; 24 | ;; Run the tests that start with the string, "hbut-defal": 25 | ;; 26 | ;; 27 | ;; Run all Hyperbole tests: 28 | ;; 29 | 30 | ;;; Code: 31 | 32 | (eval-and-compile (mapc #'require '(lisp-mode hload-path ert hact hbut hargs))) 33 | 34 | (defun hypb-ert-message-function (_msg-pat &rest _args) 35 | "Ignore the messages ert outputs so can display its test messages." 36 | ;; (identity (apply #'format msg-pat args))))))) 37 | nil) 38 | 39 | (defun hypb-ert (test-selector) 40 | "Run all ert TEST-SELECTOR tests. 41 | See documentation for `ert-select-tests' for TEST-SELECTOR types." 42 | (if (memq 'message-fn (actype:params #'ert-run-tests-interactively)) 43 | ;; Suppress ert messages so last test case message stays in the minibuffer; 44 | ;; 3rd arg message-fn available only in Emacs 27 and earlier 45 | (with-suppressed-warnings ((callargs ert)) 46 | (ert test-selector nil #'hypb-ert-message-function)) 47 | (ert test-selector)) 48 | ;; ERT can display a long internal data structure as a result, so 49 | ;; replace it in the minibuffer with a blank message. 50 | (message "")) 51 | 52 | (defun hypb-ert-run-test (test-name) 53 | "Run the specified TEST-NAME ert test." 54 | (hypb-ert-require-libraries) 55 | (let ((test-sym (intern-soft test-name))) 56 | (if test-sym 57 | (hypb-ert test-sym) 58 | (user-error "Invalid test name: %s" test-name)))) 59 | 60 | (defun hypb-ert-run-tests (test-selector) 61 | "Run the specified TEST-SELECTOR defined ert test. 62 | See documentation for `ert-select-tests' for TEST-SELECTOR types." 63 | (hypb-ert-require-libraries) 64 | (hypb-ert (regexp-quote test-selector))) 65 | 66 | (defun hypb-ert-get-require-symbols () 67 | "Return the list of test Lisp library symbols to require." 68 | (mapcar (lambda (file) 69 | (intern (substring file 0 -3))) 70 | (directory-files (expand-file-name "test" hyperb:dir) nil "^[a-zA-Z].*\\.el$"))) 71 | 72 | (defun hypb-ert-require-libraries () 73 | "Load all Hyperbole ert test symbols." 74 | (mapc #'require (hypb-ert-get-require-symbols))) 75 | 76 | (defal hyperbole-run-test "hypb-ert-run-test" 77 | "Run a Hyperbole regression test by double-quoted string name.") 78 | 79 | (defal hyperbole-run-tests "hypb-ert-run-tests" 80 | "Run a set of Hyperbole regression tests given by TEST-SELECTOR. 81 | See documentation for `ert-select-tests' for TEST-SELECTOR types.") 82 | 83 | (defun hypb-ert-run-all-tests () 84 | "Run every Hyperbole ert test." 85 | (interactive) 86 | (hypb-ert-require-libraries) 87 | (hypb-ert t)) 88 | 89 | ;; The following expression is true only when an ert-deftest has been 90 | ;; instrumented by edebug: 91 | ;; (memq 'edebug-enter (flatten-tree (ert-test-body (ert-get-test test-sym)))) 92 | 93 | (defun hypb-ert-def-at-p (&optional start-end-flag) 94 | "Return test name if on the name in the first line of an ert test def. 95 | With optional START-END-FLAG, return a list of (test-name start-pos end-pos)." 96 | (unless (or (eolp) 97 | (memq (char-after (point)) 98 | '(?\( ?\) ?\[ ?\] ?{ ?} ?< ?>))) 99 | (save-excursion 100 | (beginning-of-line) 101 | (when (looking-at (concat "(ert-deftest\\(-async\\)?[ \t]+" 102 | "\\(" lisp-mode-symbol-regexp "\\)" 103 | "\\s-*(")) 104 | (if start-end-flag 105 | (list (match-string-no-properties 2) (match-beginning 2) (match-end 2)) 106 | (match-string-no-properties 2)))))) 107 | 108 | (defun hypb-ert-run-test-at-definition (&optional edebug-it) 109 | "Eval and run any Hyperbole ert test defined at point and return t. 110 | Otherwise, return nil. Point should be on the text of the first 111 | line of an ert test def. With optional EDEBUG-IT non-nil (when 112 | the assist-key is pressed), edebug the test when it is run." 113 | (let* ((test-name (hypb-ert-def-at-p)) 114 | (test-sym (intern-soft test-name))) 115 | (when test-name 116 | ;; Ensure run the latest version of the test, either with the 117 | ;; edebugger if `edebug-it' is non-nil; otherwise, with the 118 | ;; normal evaluator. 119 | (if edebug-it 120 | (edebug-defun) 121 | (eval-defun nil)) 122 | (unless test-sym 123 | (setq test-sym (intern-soft test-name))) 124 | (when (and test-sym (ert-test-boundp test-sym)) 125 | (when (and (hypb:buffer-file-name) (string-prefix-p hyperb:dir (hypb:buffer-file-name))) 126 | (hypb-ert-require-libraries)) 127 | (when (hypb-ert test-sym) 128 | t))))) 129 | 130 | (defib hyperbole-run-test-definition () 131 | "If on the name in the first line of an ert test def, eval and run the test. 132 | With an Assist Key press instead, edebug the test and step through it." 133 | (let ((test-name-and-positions (hypb-ert-def-at-p t))) 134 | (when test-name-and-positions 135 | (apply #'ibut:label-set test-name-and-positions) 136 | (hact 'hypb-ert-run-test-at-definition)))) 137 | 138 | (defun hyperbole-run-test-definition:help (_hbut) 139 | "If on the name in the first line of an ert test def, edebug the test." 140 | (hypb-ert-run-test-at-definition t)) 141 | 142 | (provide 'hypb-ert) 143 | ;;; hypb-ert.el ends here 144 | -------------------------------------------------------------------------------- /hypb-maintenance.el: -------------------------------------------------------------------------------- 1 | ;;; hypb-maintenance.el --- functions for maintenance tasks -*- lexical-binding: t; -*- 2 | ;; 3 | ;; Author: Mats Lidell 4 | ;; 5 | ;; Orig-Date: 31-Mar-21 at 21:11:00 6 | ;; Last-Mod: 12-Mar-24 at 22:36:34 by Bob Weiner 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 1991-2022 Free Software Foundation, Inc. 11 | ;; See the "HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | 15 | ;;; Commentary: 16 | 17 | ;;; Code: 18 | (require 'kexport "kotl/kexport") 19 | (require 'kimport "kotl/kimport") 20 | 21 | (defvar hypb:web-repo-location "../hyweb/hyperbole/" 22 | "The location of hyperbole repo for the web pages.") 23 | 24 | (defconst hypb:hy-news-header 25 | " 26 | 27 | 28 | 29 | 30 | 31 | 32 |

What's New in GNU Hyperbole

33 |
 34 | "
 35 |   "HY_NEWS html header.")
 36 | 
 37 | (defconst hypb:hy-news-footer
 38 |   "  
39 | 40 | 41 | " 42 | "HY_NEWS html footer.") 43 | 44 | 45 | (defun hypb:web-repo-update () 46 | "Update the Hyperbole web repository from sources. 47 | Point `hypb:web-repo-location' to where the web repo is located." 48 | (interactive) 49 | 50 | ;; HY_NEWS 51 | (with-temp-file (concat hypb:web-repo-location "HY-NEWS.html") 52 | (insert hypb:hy-news-header) 53 | (insert-file-contents "HY-NEWS") 54 | (save-excursion 55 | (let ((beg (point))) 56 | (search-forward "====") 57 | (beginning-of-line) 58 | (delete-region beg (point)))) 59 | (indent-region (point) (point-max) 3) 60 | (goto-char (point-max)) 61 | (insert hypb:hy-news-footer)) 62 | 63 | ;; hyperbole.html 64 | (copy-file "README.md.html" (concat hypb:web-repo-location "hyperbole.html") t) 65 | 66 | ;; DEMO DEMO-ROLO.otl HY-ABOUT INSTALL HY-COPY COPYING MANIFEST 67 | ;; hui.el hbut.el hbdata.el hmail.el - referenced in hyperbole.el 68 | (mapc (lambda (file) (copy-file file hypb:web-repo-location t)) 69 | '("DEMO" "DEMO-ROLO.otl" "FAST-DEMO" "HY-ABOUT" "INSTALL" 70 | "HY-COPY" "COPYING" "MANIFEST" 71 | "hui.el" "hbut.el" "hbdata.el" "hib-doc-id.el" "hmail.el")) 72 | 73 | ;; man recursive 74 | (copy-directory "man" hypb:web-repo-location nil t nil) 75 | (dolist (file 76 | (file-expand-wildcards (concat hypb:web-repo-location "man/im/*.eps"))) 77 | (delete-file file)) 78 | 79 | ;; DEMO.html and FAST-DEMO.html 80 | (dolist (file '("DEMO" "FAST-DEMO")) 81 | (let ((export-buffer (make-temp-name "export"))) 82 | (kimport:star-outline file export-buffer) 83 | (kexport:html export-buffer (concat hypb:web-repo-location file ".html") nil) 84 | (with-current-buffer export-buffer 85 | (set-buffer-modified-p nil) 86 | (kill-buffer)))) 87 | 88 | ;; koutline-example.html 89 | (let ((example-src-name "kotl/EXAMPLE.kotl")) 90 | (kexport:html example-src-name (concat hypb:web-repo-location "koutline-example.html") nil) 91 | (with-current-buffer (get-file-buffer example-src-name) 92 | (set-buffer-modified-p nil) 93 | (kill-buffer))) 94 | 95 | ;; HY-WHY.html 96 | (let ((hy-why-src-name "HY-WHY.kotl")) 97 | (kexport:html hy-why-src-name (concat hypb:web-repo-location "HY-WHY.html") nil) 98 | (with-current-buffer (get-file-buffer hy-why-src-name) 99 | (set-buffer-modified-p nil) 100 | (kill-buffer)) 101 | (kexport:html hy-why-src-name (concat hypb:web-repo-location "HY-WHY.html") nil)) 102 | 103 | (message "Local copy of Hyperbole website updated successfully.")) 104 | 105 | 106 | (provide 'hypb-maintenance) 107 | ;;; hypb-maintenance.el ends here 108 | -------------------------------------------------------------------------------- /hyperbole-banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rswgnu/hyperbole/db9f64b3489543b7d16ec930f69c9db34e5b70ae/hyperbole-banner.png -------------------------------------------------------------------------------- /hyrolo-demo.el: -------------------------------------------------------------------------------- 1 | ;;; hyrolo-demo.el --- Code to support DEMO introduction to HyRolo -*- lexical-binding: t; -*- 2 | ;; 3 | ;; Author: Bob Weiner 4 | ;; 5 | ;; Orig-Date: 4-Nov-17 at 13:56:47 6 | ;; Last-Mod: 30-Nov-23 at 11:55:28 by Bob Weiner 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 2017-2022 Free Software Foundation, Inc. 11 | ;; See the "HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | 15 | ;;; Commentary: 16 | 17 | ;;; Code: 18 | 19 | ;;; ************************************************************************ 20 | ;;; Requirements 21 | ;;; ************************************************************************ 22 | 23 | (require 'hyrolo-logic) 24 | 25 | ;;; ************************************************************************ 26 | ;;; Public variables 27 | ;;; ************************************************************************ 28 | 29 | (defvar hyrolo-demo-save-key nil) 30 | 31 | ;;; ************************************************************************ 32 | ;;; Public functions 33 | ;;; ************************************************************************ 34 | 35 | ;;;###autoload 36 | (defun hyrolo-demo-fgrep (string &optional max-matches) 37 | "Display rolo entries in \"DEMO-ROLO.otl\" matching STRING or a logical sexp. 38 | Display to a maximum of optional prefix arg MAX-MATCHES. 39 | Each entry is displayed with all of its sub-entries. 40 | 41 | Nil value of MAX-MATCHES means find all matches, t value means find all 42 | matches but omit file headers, negative values mean find up to the inverse of 43 | that number of entries and omit file headers. 44 | 45 | Returns number of entries matched. See also documentation for 46 | the function `hyrolo-demo-fgrep-logical' for documentation on the 47 | logical sexpression matching." 48 | (interactive "sFind rolo string (or logical sexpression): \nP") 49 | (let* ((hyrolo-file-list (list (expand-file-name "DEMO-ROLO.otl" hyperb:dir))) 50 | (match-count (hyrolo-fgrep string max-matches))) 51 | (when (and (called-interactively-p 'interactive) 52 | (zerop match-count)) 53 | ;; Let user know that they invoked the demo version of hyrolo-fgrep 54 | (message "(hyrolo-demo-fgrep): No demo matches found for '%s'" string)) 55 | match-count)) 56 | 57 | ;;;###autoload 58 | (defun hyrolo-demo-fgrep-logical (expr &optional count-only include-sub-entries no-sub-entries-out) 59 | "Display rolo entries in \"DEMO-ROLO.otl\" matching EXPR. 60 | EXPR may contain prefix logical operators. 61 | If optional COUNT-ONLY is non-nil, don't display entries, return 62 | count of matching entries only. If optional INCLUDE-SUB-ENTRIES 63 | flag is non-nil, SEXP will be applied across all sub-entries at 64 | once. Default is to apply SEXP to each entry and sub-entry 65 | separately. Entries are displayed with all of their sub-entries 66 | unless INCLUDE-SUB-ENTRIES is nil and optional NO-SUB-ENTRIES-OUT 67 | flag is non-nil. 68 | 69 | A complex example of EXPR might be: 70 | (and (or (not time card) (xor (french balloons) spanish)) teacher pet) 71 | which means: 72 | Match neither `time' nor `card' 73 | or 74 | Matches exactly one of `french balloons' or `spanish' 75 | and 76 | Matches `teacher' and `pet'. 77 | 78 | Either double quotes or parentheses may be used to group multiple words as a 79 | single argument." 80 | (interactive "sLogical rolo search: \nP\nP") 81 | (when (called-interactively-p 'any) 82 | (setq no-sub-entries-out (not no-sub-entries-out))) 83 | (let ((hyrolo-file-list (list (expand-file-name "DEMO-ROLO.otl" hyperb:dir)))) 84 | (hyrolo-fgrep-logical expr count-only include-sub-entries no-sub-entries-out))) 85 | 86 | (defun hyrolo-demo-quit () 87 | "Remove the code in this file." 88 | (interactive) 89 | (when hyrolo-demo-save-key 90 | (global-set-key "\C-x4r" hyrolo-demo-save-key)) 91 | (makunbound 'hyrolo-demo-save-key) 92 | (fmakunbound 'hyrolo-demo-fgrep) 93 | (fmakunbound 'hyrolo-demo-fgrep-logical) 94 | (setq features (delq 'hyrolo-demo features)) 95 | (mapc (lambda (buf) (when (get-buffer buf) (kill-buffer buf))) 96 | '("*Hyperbole Rolo*" "DEMO-ROLO.otl")) 97 | (load "hyperbole-autoloads") 98 | (fmakunbound 'hyrolo-demo-quit) 99 | (message "HyRolo demo code removed and {C-x 4 r} key binding reset.")) 100 | 101 | ;;; ************************************************************************ 102 | ;;; Key Bindings 103 | ;;; ************************************************************************ 104 | 105 | (unless (eq (key-binding "\C-x4r") #'hyrolo-demo-fgrep) 106 | (setq hyrolo-demo-save-key (key-binding "\C-x4r"))) 107 | 108 | (global-set-key "\C-x4r" 'hyrolo-demo-fgrep) 109 | 110 | (provide 'hyrolo-demo) 111 | ;;; hyrolo-demo.el ends here 112 | -------------------------------------------------------------------------------- /hyrolo-menu.el: -------------------------------------------------------------------------------- 1 | ;;; hyrolo-menu.el --- Pulldown and popup menus of HyRolo commands -*- lexical-binding: t; -*- 2 | ;; 3 | ;; Author: Bob Weiner 4 | ;; 5 | ;; Orig-Date: 28-Oct-94 at 10:59:44 6 | ;; Last-Mod: 19-Aug-24 at 23:29:52 by Bob Weiner 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 1994-2022 Free Software Foundation, Inc. 11 | ;; See the "HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | 15 | ;;; Commentary: 16 | 17 | ;;; Code: 18 | ;;; ************************************************************************ 19 | ;;; Other required Elisp libraries 20 | ;;; ************************************************************************ 21 | 22 | (require 'easymenu) 23 | (require 'hyrolo) 24 | 25 | ;;; ************************************************************************ 26 | ;;; Public variables 27 | ;;; ************************************************************************ 28 | 29 | (defconst infodock-hyrolo-menu 30 | (delq nil 31 | (list 32 | "Rolo" 33 | ["Manual" (id-info "(hyperbole)HyRolo") t] 34 | "----" 35 | ;; Delete Rolo menu from all menubars. 36 | ["Remove-This-Menu" (hui-menu-remove Rolo hyrolo-mode-map) t] 37 | "----" 38 | ["Add-Entry" (id-tool-invoke 'hyrolo-add) t] 39 | (when (fboundp 'consult-grep) ;; allow for autoloading 40 | ;; Interactively narrow HyRolo matches using Consult/Vertico. 41 | ["Consult-Find" (id-tool-invoke 'hyrolo-consult-grep) t]) 42 | ["Delete-Entry" (id-tool-invoke 'hyrolo-kill) t] 43 | ["Display-Prior-Matches" (id-tool-invoke 'hyrolo-display-matches) t] 44 | ["Edit-Entry" (id-tool-invoke 'hyrolo-edit) t] 45 | ["Find-HyRolo-File" (id-tool-invoke 46 | (lambda () 47 | (require 'hyrolo) 48 | (hyrolo-find-file))) 49 | t] 50 | (when (fboundp 'helm-org-rifle-files) ;; allow for autoloading 51 | ;; Interactively narrow HyRolo matches using Helm. 52 | ["Helm-Find" (id-tool-invoke 'hyrolo-helm-org-rifle) t]) 53 | ["Insert-Entry-at-Point" (id-tool-invoke 'hyrolo-yank) t] 54 | ["Mail-to-Address" (id-tool-invoke 'hyrolo-mail-to) t] 55 | ["Search-for-Regexp" (id-tool-invoke 'hyrolo-grep) t] 56 | ["Search-for-String" (id-tool-invoke 'hyrolo-fgrep) t] 57 | ["Search-for-Word" (id-tool-invoke 'hyrolo-word) t] 58 | ["Sort-Entries" (id-tool-invoke 'hyrolo-sort) t] 59 | ["Tag-Find" (id-tool-invoke 'hyrolo-tags-view) t]))) 60 | 61 | (defconst hyrolo-menu-common-body 62 | '( 63 | ("Move" 64 | ["Scroll-Backward" scroll-down t] 65 | ["Scroll-Forward" scroll-up t] 66 | ["To-Beginning" beginning-of-buffer t] 67 | ["To-End" end-of-buffer t] 68 | "----" 69 | ["To-Next-Entry" hyrolo-outline-next-visible-heading t] 70 | ["To-Next-Same-Level" hyrolo-outline-forward-same-level t] 71 | ["To-Previous-Entry" hyrolo-outline-previous-visible-heading t] 72 | ["To-Previous-Same-Level" hyrolo-outline-backward-same-level t] 73 | ["Up-a-Level" hyrolo-outline-up-heading t]) 74 | ("Outline" 75 | ["Hide (Collapse)" hyrolo-outline-hide-subtree t] 76 | ["Show (Expand)" hyrolo-outline-show-subtree t] 77 | ["Show-All" hyrolo-outline-show-all t] 78 | ["Show-Only-First-Line" hyrolo-outline-hide-body t])) 79 | "The middle menu entries common to all HyRolo menus.") 80 | 81 | (defconst id-popup-hyrolo-menu 82 | (append 83 | '("Rolo" 84 | ["Help" describe-mode t] 85 | ["Manual" (id-info "(hyperbole)Rolo Keys") t] 86 | "----" 87 | ["Edit-Entry-at-Point" hyrolo-edit-entry t] 88 | "----" 89 | ["Locate-Entry-Isearch" hyrolo-locate t] 90 | ["Next-Match" hyrolo-next-match t] 91 | ["Previous-Match" hyrolo-previous-match t] 92 | "----") 93 | `,@hyrolo-menu-common-body 94 | (list infodock-hyrolo-menu) 95 | '("----" 96 | ["Quit" (id-tool-quit '(hyrolo-quit)) t]))) 97 | 98 | ;;; ************************************************************************ 99 | ;;; Public functions 100 | ;;; ************************************************************************ 101 | 102 | (defun hyrolo-menubar-menu () 103 | "Add a HyRolo menu to the rolo match buffer menubar." 104 | (define-key hyrolo-mode-map [C-down-mouse-3] 'hyrolo-popup-menu) 105 | (define-key hyrolo-mode-map [C-mouse-3] nil) 106 | (unless (global-key-binding [menu-bar Rolo]) 107 | (easy-menu-define nil hyrolo-mode-map "Rolo Menubar Menu" id-popup-hyrolo-menu) 108 | ;; Force a menu-bar update. 109 | (force-mode-line-update))) 110 | 111 | (defun hyrolo-popup-menu (event) 112 | "Popup the Hyperbole Rolo match buffer menu." 113 | (interactive "@e") 114 | (mouse-set-point event) 115 | (popup-menu id-popup-hyrolo-menu)) 116 | 117 | (add-hook 'hyrolo-mode-hook #'hyrolo-menubar-menu) 118 | 119 | (provide 'hyrolo-menu) 120 | 121 | ;;; hyrolo-menu.el ends here 122 | -------------------------------------------------------------------------------- /hywiki/HyWiki.org: -------------------------------------------------------------------------------- 1 | ;;; -*- org-link-descriptive: nil -*- 2 | 3 | * HyWiki 4 | 5 | This is Hyperbole's markup-free personal wiki system for note-taking 6 | and automatic wiki word highlighting and hyperlinking. It uses Org 7 | mode for note taking and adds automatic hyperlinking of HyWikiWords 8 | within Org files in `hywiki-directory' (default = "~/hywiki"), where 9 | a HyWikiWord is a capitalized word that contains upper and lowercase 10 | letters only and has a corresponding HyWikiWord.org wiki page file 11 | below `hywiki-directory'. HyWikiWords require no delimiters. 12 | 13 | * HyWikiWords 14 | 15 | HyWikiWords are also recognized in text buffers after the global 16 | minor mode, `hywiki-mode' is enabled via {M-x hywiki-mode RET}. To 17 | create or jump to a HyWiki page, simply type out a potential 18 | HyWikiWord or move point onto one and press the Action Key {M-RET}. 19 | This will create the associated page if it does not exist. This 20 | also highlights any other instances of HyWikiWords across all 21 | visible Emacs windows. HyWiki is built for scalability and has been 22 | tested to be performant with 10,000 HyWikiWords. 23 | 24 | Once Hyperbole has been loaded and activated, HyWikiWords (with or 25 | without delimiters) are automatically highlighted and active in 26 | the following contexts: 27 | - HyWiki page buffers; 28 | - non-special text buffers, when `hywiki-mode' is enabled; 29 | - comments of programming buffers, when `hywiki-mode' is enabled. 30 | 31 | As HyWikiWords are typed, highlighting occurs after a trailing 32 | whitespace or punctuation character is added, or when an opening 33 | or closing parenthesis or curly brace is added to surround the 34 | HyWikiWord. Since Org links use double square brackets and Org 35 | targets use double or triple angle brackets, HyWikiWords within 36 | these delimiters are ignored. 37 | 38 | * Org-style HyWiki Links 39 | 40 | You can also create Org links to HyWikiWords in any non-special text 41 | buffer by surrounding them with double square brackets and the 42 | 'hy:' prefix, as in: [[hy:MyWikiWord]]. If you set 43 | `hywiki-org-link-type-required' to `nil', then you don't need the 44 | prefix, e.g. [[MyWikiWord]]; existing HyWiki page names then will 45 | override Org's standard handling of such links. To prevent Org 46 | mode's binding of {M-RET} from splitting lines and creating new 47 | headlines when on a HyWiki word whose page has not yet been 48 | created, set `hsys-org-enable-smart-keys' to `t' so that 49 | Hyperbole's Action Key does the right thing in this context. 50 | 51 | * HyWiki Settings 52 | 53 | The custom setting, 'hywiki-word-highlight-flag' (default = 't'), 54 | means HyWikiWords will be auto-highlighted within HyWiki pages. 55 | Outside of such pages, 'hywiki-mode' must also be enabled for such 56 | auto-highlighting. 57 | 58 | The custom setting, 'hywiki-exclude-major-modes' (default = 'nil'), is 59 | a list of major modes to exclude from HyWikiWord auto-highlighting and 60 | recognition. 61 | 62 | Within programming modes, HyWikiWords are highlighted and hyperlinked 63 | within comments only. For programming modes in which you want 64 | HyWikiWords recognized everywhere, add them to the custom setting, 65 | 'hywiki-highlight-all-in-prog-modes' (default = 66 | ''(lisp-interaction-mode)'). 67 | 68 | * hywiki-word Implicit Button Type 69 | 70 | HyWiki adds one implicit button type to Hyperbole: 'hywiki-word', 71 | which creates and displays HyWikiWord pages. This is one of the lowest 72 | priority implicit button types so that it triggers only when other types 73 | are not recognized first. 74 | -------------------------------------------------------------------------------- /hywiki/HyWikiMenus.org: -------------------------------------------------------------------------------- 1 | * HyWiki Menu 2 | 3 | The HyWiki minibuffer menu offers quick access to important HyWiki 4 | features. It looks like this: 5 | 6 | HyWiki> Act Create Edit Grep Help Info Link Publish Search 7 | 8 | Below are descriptions of each menu item. 9 | 10 | ** Act 11 | Activate HyWikiWord link at point. 12 | ** Create 13 | Create and display a new HyWiki page. Shows existing page names to 14 | aid in new naming. 15 | ** Edit 16 | Prompt with completion for and display a HyWiki page ready for 17 | editing. 18 | ** Grep 19 | Grep over HyWiki pages with interactive 'hywiki-consult-grep'. 20 | ** Help 21 | Report on a HyWikiWord's attributes. 22 | ** Info 23 | Display Hyperbole manual section on HyWiki. 24 | ** Link 25 | Prompt for and add a link at point to a HyWiki page. 26 | ** Publish 27 | Publish modified pages in the HyWiki to HTML; prefix arg to publish 28 | all pages. 29 | ** Search 30 | Use 'hywiki-consult-grep' to show occurrences of a prompted for 31 | HyWikiWord. 32 | 33 | -------------------------------------------------------------------------------- /hywiki/Publishing.org: -------------------------------------------------------------------------------- 1 | * Publishing a HyWiki 2 | 3 | A HyWiki can be exported to HTML for publishing to the web via Org 4 | mode's publish a project feature. {C-h h h p} or {M-x 5 | hywiki-publish-to-html } publishes any changed files in the HyWiki. 6 | Give that command a prefix argument to force republishing of all HyWiki 7 | pages. 8 | 9 | The full set of HyWiki-specific Org publish properties are set in the 10 | variable 'hywiki-org-publish-project-alist'. When the HyWiki code is 11 | loaded into Emacs, it automatically integrates these properties with 12 | Org's publishing framework, so when in a HyWiki page, you can use 13 | Org's standard {C-c C-e P p} current project publish command if you 14 | prefer. 15 | 16 | There are a few publishing settings you can customize prior to loading 17 | Hyperbole's HyWiki code. 18 | 19 | HyWiki html files are saved in: (hywiki-org-get-publish-property 20 | :publishing-directory). Customize this directory with: {M-x 21 | customize-variable hywiki-org-publishing-directory } 22 | 23 | HyWiki html files are generated by the function given by: 24 | (hywiki-org-get-publish-property :publishing-function). Customize the 25 | value of this function if necessary with: {M-x customize-variable 26 | hywiki-org-publishing-function } 27 | -------------------------------------------------------------------------------- /install-test/MANIFEST: -------------------------------------------------------------------------------- 1 | --- HYPERBOLE INSTALLATION TEST CONFIGURATIONS --- 2 | elpa/.emacs - Elpa package personal configuration 3 | elpa-devel/.emacs - Elpa-devel package personal configuration 4 | local-install-test.sh - Run one or more test installations 5 | straight/.emacs - Straight git package personal configuration 6 | tarball/.emacs - Manual tarball personal configuration 7 | tarball/install-local.sh - Manual tarball download and build script 8 | local/.emacs - Straight git package from local repo and branch 9 | elpaca/.emacs - Elpaca package configuration (elpa-devel install) 10 | -------------------------------------------------------------------------------- /install-test/elpa-devel/.emacs: -------------------------------------------------------------------------------- 1 | ;; .emacs 2 | 3 | (when (< emacs-major-version 27) 4 | (error "Hyperbole requires Emacs 27 or above; you are running version %d" emacs-major-version)) 5 | (require 'package) 6 | (setq package-native-compile t) 7 | (add-to-list 'package-archives '("gnu-devel" . "https://elpa.gnu.org/devel/")) 8 | (unless (package-installed-p 'hyperbole) 9 | (package-refresh-contents) 10 | (package-install 'hyperbole)) 11 | (hyperbole-mode 1) 12 | 13 | (message "%s" "Hyperbole successfully installed and activated") 14 | -------------------------------------------------------------------------------- /install-test/elpa/.emacs: -------------------------------------------------------------------------------- 1 | ;; .emacs 2 | 3 | (when (< emacs-major-version 27) 4 | (error "Hyperbole requires Emacs 27 or above; you are running version %d" emacs-major-version)) 5 | (require 'package) 6 | (setq package-native-compile t) 7 | (unless (package-installed-p 'hyperbole) 8 | (package-refresh-contents) 9 | (package-install 'hyperbole)) 10 | (hyperbole-mode 1) 11 | 12 | (message "%s" "Hyperbole successfully installed and activated") 13 | -------------------------------------------------------------------------------- /install-test/elpaca/.emacs: -------------------------------------------------------------------------------- 1 | ;; .emacs 2 | 3 | (when (< emacs-major-version 27) 4 | (error "Hyperbole requires Emacs 27 or above; you are running version %d" emacs-major-version)) 5 | 6 | ;; elpaca 7 | (defvar elpaca-installer-version 0.5) 8 | (defvar elpaca-directory (expand-file-name "elpaca/" user-emacs-directory)) 9 | (defvar elpaca-builds-directory (expand-file-name "builds/" elpaca-directory)) 10 | (defvar elpaca-repos-directory (expand-file-name "repos/" elpaca-directory)) 11 | (defvar elpaca-order '(elpaca :repo "https://github.com/progfolio/elpaca.git" 12 | :ref nil 13 | :files (:defaults (:exclude "extensions")) 14 | :build (:not elpaca--activate-package))) 15 | (let* ((repo (expand-file-name "elpaca/" elpaca-repos-directory)) 16 | (build (expand-file-name "elpaca/" elpaca-builds-directory)) 17 | (order (cdr elpaca-order)) 18 | (default-directory repo)) 19 | (add-to-list 'load-path (if (file-exists-p build) build repo)) 20 | (unless (file-exists-p repo) 21 | (make-directory repo t) 22 | (when (< emacs-major-version 28) (require 'subr-x)) 23 | (condition-case-unless-debug err 24 | (if-let ((buffer (pop-to-buffer-same-window "*elpaca-bootstrap*")) 25 | ((zerop (call-process "git" nil buffer t "clone" 26 | (plist-get order :repo) repo))) 27 | ((zerop (call-process "git" nil buffer t "checkout" 28 | (or (plist-get order :ref) "--")))) 29 | (emacs (concat invocation-directory invocation-name)) 30 | ((zerop (call-process emacs nil buffer nil "-Q" "-L" "." "--batch" 31 | "--eval" "(byte-recompile-directory \".\" 0 'force)"))) 32 | ((require 'elpaca)) 33 | ((elpaca-generate-autoloads "elpaca" repo))) 34 | (progn (message "%s" (buffer-string)) (kill-buffer buffer)) 35 | (error "%s" (with-current-buffer buffer (buffer-string)))) 36 | ((error) (warn "%s" err) (delete-directory repo 'recursive)))) 37 | (unless (require 'elpaca-autoloads nil t) 38 | (require 'elpaca) 39 | (elpaca-generate-autoloads "elpaca" repo) 40 | (load "./elpaca-autoloads"))) 41 | (add-hook 'after-init-hook #'elpaca-process-queues) 42 | (elpaca `(,@elpaca-order)) 43 | 44 | ;; Install use-package support 45 | (elpaca elpaca-use-package 46 | ;; Enable :elpaca use-package keyword. 47 | (elpaca-use-package-mode) 48 | ;; Assume :elpaca t unless otherwise specified. 49 | (setq elpaca-use-package-by-default t)) 50 | 51 | ;; Block until current queue processed. 52 | (elpaca-wait) 53 | 54 | ;; (setq package-native-compile t) 55 | 56 | (use-package hyperbole 57 | :pin #:elpa-devel 58 | :elpaca (:files ("*" "man/*" (:exclude "man")))) 59 | 60 | (elpaca-process-queues) 61 | (elpaca-wait) 62 | 63 | ;; (unless (package-installed-p 'hyperbole) 64 | ;; (package-refresh-contents) 65 | ;; (package-install 'hyperbole)) 66 | (elpaca nil (hyperbole-mode 1)) 67 | 68 | (elpaca nil (message "%s" "Hyperbole successfully installed and activated")) 69 | -------------------------------------------------------------------------------- /install-test/local-install-test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo *** Install test *** 4 | 5 | set -e 6 | 7 | install_method="$1" 8 | 9 | app=/tmp/hypb-$$ 10 | 11 | mkdir -p $app 12 | cp -a * $app 13 | export HOME=$app/$install_method 14 | 15 | [ -e $app/$install_method/install-local.sh ] && cd $app/$install_method && ./install-local.sh 16 | 17 | cd $app/$install_method 18 | 19 | if [ -n "$2" ] 20 | then 21 | export LOCAL_HYPB_REPO=$2 22 | export LOCAL_HYPB_BRANCH=$3 23 | fi 24 | 25 | ## Initial install with ert tests 26 | emacs --batch -l $app/$install_method/.emacs \ 27 | --eval '(load (expand-file-name "test/hy-test-dependencies.el" hyperb:dir))' \ 28 | -l hypb-ert \ 29 | --eval "(hypb-ert-require-libraries)" \ 30 | -f ert-run-tests-batch-and-exit 31 | 32 | ## Startup again interactive - check hyperbole is found 33 | emacs -nw --eval "(if (boundp 'hyperb:version) (kill-emacs 0) (kill-emacs 1))" 34 | -------------------------------------------------------------------------------- /install-test/local/.emacs: -------------------------------------------------------------------------------- 1 | ;; Use this in your Emacs init file to install Straight 2 | (progn 3 | (when (< emacs-major-version 27) 4 | (error "Hyperbole requires Emacs 27 or above; you are running version %d" emacs-major-version)) 5 | (defvar bootstrap-version) 6 | (setq package-enable-at-startup nil) 7 | (let ((bootstrap-file 8 | (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory)) 9 | (bootstrap-version 5)) 10 | (unless (file-exists-p bootstrap-file) 11 | (with-current-buffer 12 | (url-retrieve-synchronously 13 | "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el" 14 | 'silent 'inhibit-cookies) 15 | (goto-char (point-max)) 16 | (eval-print-last-sexp))) 17 | (load bootstrap-file nil 'nomessage))) 18 | 19 | (setq package-native-compile t) 20 | 21 | (straight-use-package 22 | (list 23 | 'hyperbole 24 | :host nil 25 | :repo (getenv "LOCAL_HYPB_REPO") 26 | :branch (getenv "LOCAL_HYPB_BRANCH") 27 | :config '(hyperbole-mode 1))) 28 | 29 | (hyperbole-mode 1) 30 | 31 | (message "%s" "Hyperbole successfully installed and activated") 32 | -------------------------------------------------------------------------------- /install-test/melpa/.emacs: -------------------------------------------------------------------------------- 1 | ;; .emacs 2 | 3 | (when (< emacs-major-version 27) 4 | (error "Hyperbole requires Emacs 27 or above; you are running version %d" emacs-major-version)) 5 | (require 'package) 6 | (setq package-native-compile t) 7 | (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/")) 8 | (unless (package-installed-p 'hyperbole) 9 | (package-refresh-contents) 10 | (package-install 'hyperbole)) 11 | (hyperbole-mode 1) 12 | 13 | (message "%s" "Hyperbole successfully installed and activated") 14 | -------------------------------------------------------------------------------- /install-test/straight/.emacs: -------------------------------------------------------------------------------- 1 | ;; Use this in your Emacs init file to install Straight 2 | (progn 3 | (when (< emacs-major-version 27) 4 | (error "Hyperbole requires Emacs 27 or above; you are running version %d" emacs-major-version)) 5 | (defvar bootstrap-version) 6 | (setq package-enable-at-startup nil) 7 | (let ((bootstrap-file 8 | (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory)) 9 | (bootstrap-version 5)) 10 | (unless (file-exists-p bootstrap-file) 11 | (with-current-buffer 12 | (url-retrieve-synchronously 13 | "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el" 14 | 'silent 'inhibit-cookies) 15 | (goto-char (point-max)) 16 | (eval-print-last-sexp))) 17 | (load bootstrap-file nil 'nomessage))) 18 | 19 | ;; Then use this to install Hyperbole 20 | (straight-use-package 21 | '(hyperbole 22 | :host nil 23 | :repo "https://git.savannah.gnu.org/git/hyperbole.git" 24 | :config (hyperbole-mode 1))) 25 | 26 | (hyperbole-mode 1) 27 | 28 | (message "%s" "Hyperbole successfully installed and activated") 29 | -------------------------------------------------------------------------------- /install-test/tarball/.emacs: -------------------------------------------------------------------------------- 1 | ;;; tarball -- hyperbole installed from a tar ball 2 | 3 | (when (< emacs-major-version 27) 4 | (error "Hyperbole requires Emacs 27 or above; you are running version %d" emacs-major-version)) 5 | (unless (and (featurep 'hyperbole) hyperbole-mode) 6 | (push (expand-file-name "hyperbole" (getenv "HOME")) load-path) 7 | (require 'hyperbole) 8 | (hyperbole-mode 1)) 9 | 10 | (message "%s" "Hyperbole successfully installed and activated") 11 | -------------------------------------------------------------------------------- /install-test/tarball/install-local.sh: -------------------------------------------------------------------------------- 1 | curl -O https://elpa.gnu.org/devel/hyperbole.tar 2 | tar -xf hyperbole.tar 3 | rm hyperbole.tar 4 | ln -s hyperbole* hyperbole 5 | cd hyperbole 6 | make bin eln 7 | 8 | -------------------------------------------------------------------------------- /interactive-demos/HYROLO: -------------------------------------------------------------------------------- 1 | * HyRolo 2 | 3 | Think of HyRolo as a contact book, it keeps your contacts in an easy to read 4 | file with plenty of built in functions for things such as find, adding, and 5 | editing entries, to name a few. 6 | 7 | 8 | Let's start by creating our own entry with {C-h h r a}, which will prompt you 9 | for a name. Feel free to put anything in there. After you put in a name it will 10 | take you to ~/.rolo.otl, where you can see the entry you just created. Each entry 11 | must begin with at least one "*" at the beginning of their line. Entries are 12 | usually arranged in a hierarchy, where each child's line starts with one more 13 | "*" than the previous one. After these delimiters, the entries are free-form text. 14 | Ideally you want to put entries in "lastname, firstname" so that HyRolo will 15 | automatically alphabetize them. That being said, if you prefer "firstname, lastname" 16 | then alphabetizing them is a simple command away, # <(hyrolo-sort)>. Also note 17 | that when each contact is added, a date is automatically added underneath. 18 | 19 | 20 | Your rolo file is probably looking something like 21 | * Name 22 | 23 | 24 | which is fairly basic. Let's go ahead and add a header to that to tell us that 25 | this is a person HyRolo file, as apposed to a professional one. This is done 26 | by adding in at least three equal signs above, and below the name you 27 | want for the HyRolo. It should look something like this 28 | 29 | ===================== 30 | Personal 31 | ===================== 32 | * Name 33 | 34 | 35 | ** String Searches 36 | Now let's say that you either don't want to add in a header or don't like the 37 | idea of maintaining multiple HyRolo files for Personal, Professional, etc. Good news 38 | is, we can just add a small tag to each contact (personal, professional, etc), 39 | and use string searches to find them. 40 | 41 | 42 | There are a few ways to do string searching in HyRolo, and a few commands you 43 | can use. The first being the hyrolo-grep command which will find all entries 44 | containing a regular expression. Try this with the current date, and you will 45 | see that it picks up the line(s) with the current date, but nothing else. That 46 | being said, if you type in part of the name you used in your entry, you will see 47 | that pop up and be highlighted. 48 | 49 | 50 | Another option is the hyrolo-word command which will look for full words. Unlike 51 | the grep command, if the word isn't a complete match, it won't show up. Take the first 52 | three letters of a name in your rolo and search for that with hyrolo-word, and 53 | you'll notice that the mini-buffer says "No matching entries found in rolo". 54 | 55 | 56 | The final option is hyrolo-fgrep which can search for strings or logical expressions. 57 | Essentially, it can do what grep does, but with an added twist for logical expressions. 58 | Speaking of logical searches... 59 | 60 | ** Logical Searches 61 | Similar to the regular string search, we can add logical expressions to our 62 | searches to help find what we're looking for. For now, let's add a few more 63 | entries to our rolo, such as the name Linus Torvalds, Richard Stallman, and 64 | Ken Thompson. Now that we have a more populated rolo, let's look at some 65 | uses of logical expressions in our searches. Below is a table of the kinds 66 | of logical expressions you can use. 67 | 68 | 69 | Operator Name Number of Arguments Description 70 | ===================================================================== 71 | and two or more Match entries with all args 72 | or two or more Match entries with any args 73 | xor two or more Match entries with 1 arg only 74 | not one Match entries without the arg 75 | ===================================================================== 76 | 77 | Let's say we want to look for Linus, and Ken. We would run hyolo-fgrep-logical 78 | and our input would be (or linus ken), and that will pull up both Linus and Ken, 79 | and whatever information we have for them. Keep in mind, you need the parenthesis 80 | for the function to work. 81 | 82 | 83 | Now that you know how the logical searches work, try searching your rolo for 84 | everything except Linus. 85 | 86 | 87 | ** Keys 88 | Now that we have a firm understanding of how to perform searches, what do we do 89 | with these results? That's where keys come in to play. 90 | 91 | 92 | After you preform a search, you get your results in a "rolo match buffer", 93 | '*Hyperbole Rolo', which uses 'hyrolo-mode' to simplify browsing many HyRolo 94 | matches. Let's try, and preform a search with hyrolo-grep, and when the results 95 | get pulled up, press {?}. That will pull up a summary of the available keys. 96 | 97 | 98 | Now that we know how to view our keys, let's start with {r}, which will allow 99 | us to start a new regular expression query. Let's preform a <(search)> for 100 | Linus. Now that we have our results we realize that we didn't want the information 101 | for Linus, we wanted it for Ken. Press the {r} key in the '*Hyperbole Rolo' 102 | buffer. It will prompt you for a new regular expression, type in Ken. 103 | 104 | 105 | Great, now that we have an understanding of how to use these keys, try 106 | making a search, and within that search hide the subtree for our entries. Once 107 | that is done, use the key to show them all. 108 | 109 | 110 | Once you are done with your query, and are ready to leave the rolo match buffer, 111 | use {q} to quit. This will restore your current frame to its state prior to the 112 | rolo search. 113 | -------------------------------------------------------------------------------- /kotl/MANIFEST: -------------------------------------------------------------------------------- 1 | --- HYPERBOLE KOUTLINER --- 2 | EXAMPLE.kotl - Example koutline document explaining koutliner features 3 | kcell.el - Internal representation of koutline kcells used by kviews 4 | kexport.el - Convert koutlines to other textual formats, including HTML 5 | kfile.el - Save and restore koutlines from files 6 | kfill.el - Fill and justify koutline cells 7 | kimport.el - Convert and insert other outline file formats into koutlines 8 | klabel.el - Display label handling for koutlines 9 | klink.el - Implicit reference to a Koutline kcell 10 | kmenu.el - Pulldown and popup menus for kotl-mode, the Koutliner mode 11 | kotl-mode.el - Major mode for editing koutlines and associated commands 12 | kotl-orgtbl.el - Allow use of Org minor-mode table editing in koutlines 13 | kproperty.el - Kcell in-buffer property handling for the Koutliner 14 | kview.el - Display handling of koutlines 15 | kvspec.el - Koutline view specification 16 | -------------------------------------------------------------------------------- /kotl/kproperty.el: -------------------------------------------------------------------------------- 1 | ;;; kproperty.el --- Kcell in-buffer property handling for the Koutliner -*- lexical-binding: t; -*- 2 | ;; 3 | ;; Author: Bob Weiner 4 | ;; 5 | ;; Orig-Date: 7/27/93 6 | ;; Last-Mod: 22-Sep-23 at 00:12:40 by Mats Lidell 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 1993-2021 Free Software Foundation, Inc. 11 | ;; See the "../HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | 15 | ;;; Commentary: 16 | ;; Stores and retrieves kcell properties as Emacs text properties 17 | ;; at the kcell label separator. 18 | 19 | ;;; Code: 20 | ;;; ************************************************************************ 21 | ;;; Other required Elisp libraries 22 | ;;; ************************************************************************ 23 | 24 | ;; Ensure kotl/ is in load-path. 25 | ;; (require 'hyperbole) 26 | 27 | ;;; ************************************************************************ 28 | ;;; Public functions 29 | ;;; ************************************************************************ 30 | 31 | (defun kproperty:add-properties (plist) 32 | "Add properties at point and the following character from PLIST." 33 | (kproperty:put (point) (min (+ 2 (point)) (point-max)) 34 | plist)) 35 | 36 | (defun kproperty:remove-properties (plist) 37 | "Remove properties at point and the following character from PLIST." 38 | (kproperty:remove (point) (min (+ 2 (point)) (point-max)) 39 | plist)) 40 | 41 | (defun kproperty:all-positions (property value) 42 | "Return a list of all non-narrowed positions of kcells with PROPERTY VALUE. 43 | If no kcells with PROPERTY VALUE, return nil. 44 | Use (kcell-view:start ) on each returned to get 45 | the start position of each cell's content." 46 | (kproperty:map (lambda (start _end) start) property value)) 47 | 48 | (defalias 'kproperty:get 'get-text-property) 49 | 50 | (defun kproperty:map (function property value) 51 | "Apply FUNCTION to each character with PROPERTY VALUE in the current buffer. 52 | FUNCTION is called with the start and end points of the text span, 53 | with the matching PROPERTY and with point at the start." 54 | (let ((result) 55 | (start (point-min)) 56 | end) 57 | (save-excursion 58 | (while (and (< start (point-max)) 59 | (setq start (text-property-any start (point-max) property value))) 60 | (goto-char start) 61 | (setq end (or (text-property-not-all start (point-max) property value) (point-max)) 62 | result (cons (funcall function start end) result) 63 | start end))) 64 | (nreverse result))) 65 | 66 | (defalias 'kproperty:next-single-change 'next-single-property-change) 67 | 68 | (defun kproperty:position (property value) 69 | "Return the non-narrowed buffer position of the first kcell with PROPERTY VALUE. 70 | If no kcell with PROPERTY VALUE, return nil. 71 | Use (kcell-view:start ) on the returned to get 72 | the start position of the cell's content." 73 | (text-property-any (point-min) (point-max) property value)) 74 | 75 | (defalias 'kproperty:previous-single-change 'previous-single-property-change) 76 | 77 | (defalias 'kproperty:properties 'text-properties-at) 78 | 79 | (defun kproperty:put (start end property-list &optional object) 80 | "From START to END, add PROPERTY-LIST properties to the text. 81 | The optional fourth argument, OBJECT, is the string or buffer containing the 82 | text. Text inserted before or after this region does not inherit the added 83 | properties." 84 | (add-text-properties 85 | start end (append property-list '(rear-nonsticky t)) object)) 86 | 87 | (defun kproperty:remove (start end property-list &optional object) 88 | "From START to END, remove the text properties in PROPERTY-LIST. 89 | The optional fourth argument, OBJECT, is the string or buffer containing the 90 | text. PROPERTY-LIST should be a plist; if the value of a property is 91 | non-nil, then only a property with a matching value will be removed. 92 | Return t if any property was changed, nil otherwise." 93 | (let ((changed) plist property value next) 94 | (while property-list 95 | (setq property (car property-list) 96 | value (car (cdr property-list)) 97 | plist (list property value) 98 | property-list (nthcdr 2 property-list) 99 | next start) 100 | (while (setq next (text-property-any next end property value object)) 101 | (remove-text-properties next (1+ next) plist object) 102 | (setq changed t next (1+ next)))) 103 | changed)) 104 | 105 | (defun kproperty:replace-separator (new-label-separator old-sep-len) 106 | "Replace from point forward each cell's label separator with NEW-LABEL-SEPARATOR. 107 | OLD-SEP-LEN is the length of the separator being replaced." 108 | (let (pos 109 | properties) 110 | (while (setq pos (kproperty:next-single-change (point) 'kcell)) 111 | (goto-char pos) 112 | (setq properties (text-properties-at pos)) 113 | ;; Replace label-separator while maintaining cell properties. 114 | (insert new-label-separator) 115 | (add-text-properties pos (+ pos 2) properties) 116 | (delete-region (point) (+ (point) old-sep-len))))) 117 | 118 | (defun kproperty:set (property value) 119 | "Set PROPERTY of character at point and the following character to VALUE." 120 | (kproperty:add-properties (list property value))) 121 | 122 | (provide 'kproperty) 123 | 124 | ;;; kproperty.el ends here 125 | -------------------------------------------------------------------------------- /man/.dir-locals.el: -------------------------------------------------------------------------------- 1 | ((texinfo-mode 2 | . ((before-save-hook 3 | . (lambda () 4 | (let ((day (format-time-string "%d" (current-time))) 5 | (month (capitalize (format-time-string "%B" (current-time)))) 6 | (year (format-time-string "%Y" (current-time)))) 7 | (save-excursion 8 | (goto-char (point-min)) 9 | (when (re-search-forward "\\(@set UPDATED [[:word:]]+, [[:digit:]]+\\)" nil t) 10 | (replace-match (format "@set UPDATED %s, %s" month year) nil t nil nil)) 11 | (goto-char (point-min)) 12 | (when (re-search-forward "\\(@set UPDATED-MONTH [[:word:]]+ [[:digit:]]+\\)" nil t) 13 | (replace-match (format "@set UPDATED-MONTH %s %s" month year) nil t nil nil)) 14 | (goto-char (point-min)) 15 | (when (re-search-forward "\\(Printed [[:word:]]+ [[:digit:]]+, [[:digit:]]+\.\\)" nil t) 16 | (replace-match (format "Printed %s %s, %s." month day year) nil t nil nil)) 17 | (goto-char (point-min)) 18 | (when (re-search-forward "\\([[:word:]]+ [[:digit:]]+, [[:digit:]]+ @c AUTO-REPLACE-ON-SAVE\\)" nil t) 19 | (replace-match (format "%s %s, %s @c AUTO-REPLACE-ON-SAVE" month day year) nil t nil nil))))))))) 20 | -------------------------------------------------------------------------------- /man/dir: -------------------------------------------------------------------------------- 1 | This is the file .../info/dir, which contains the 2 | topmost node of the Info hierarchy, called (dir)Top. 3 | The first time you invoke Info you start off looking at this node. 4 |  5 | File: dir, Node: Top This is the top of the INFO tree 6 | 7 | This (the Directory node) gives a menu of major topics. 8 | Typing "q" exits, "?" lists all Info commands, "d" returns here, 9 | "h" gives a primer for first-timers, 10 | "mEmacs" visits the Emacs manual, etc. 11 | 12 | In Emacs, you can click mouse button 2 on a menu item or cross reference 13 | to select it. 14 | 15 | * Menu: 16 | 17 | Emacs 18 | * Hyperbole: (hyperbole). The Everyday Hypertextual Information Manager. 19 | Use {C-h h d d} for a demonstration. 20 | GNU Hyperbole offers context-sensitive 21 | mouse and keyboard keys that do the right 22 | thing, a powerful personal Wiki generator, 23 | contact manager, an advanced, auto-numbered 24 | outliner with hyperlink anchors for each 25 | outline cell, and easily editable and extensible 26 | hyperlink buttons, even embeddable within mail 27 | and news messages. 28 | 29 | -------------------------------------------------------------------------------- /man/hyperbole.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rswgnu/hyperbole/db9f64b3489543b7d16ec930f69c9db34e5b70ae/man/hyperbole.pdf -------------------------------------------------------------------------------- /man/im/C-hh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rswgnu/hyperbole/db9f64b3489543b7d16ec930f69c9db34e5b70ae/man/im/C-hh.png -------------------------------------------------------------------------------- /man/im/action-key-animation.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rswgnu/hyperbole/db9f64b3489543b7d16ec930f69c9db34e5b70ae/man/im/action-key-animation.gif -------------------------------------------------------------------------------- /man/im/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rswgnu/hyperbole/db9f64b3489543b7d16ec930f69c9db34e5b70ae/man/im/demo.png -------------------------------------------------------------------------------- /man/im/hyperbole-cv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rswgnu/hyperbole/db9f64b3489543b7d16ec930f69c9db34e5b70ae/man/im/hyperbole-cv.png -------------------------------------------------------------------------------- /man/im/koutliner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rswgnu/hyperbole/db9f64b3489543b7d16ec930f69c9db34e5b70ae/man/im/koutliner.png -------------------------------------------------------------------------------- /man/im/menu-customization.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rswgnu/hyperbole/db9f64b3489543b7d16ec930f69c9db34e5b70ae/man/im/menu-customization.png -------------------------------------------------------------------------------- /man/im/menu-display-referents.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rswgnu/hyperbole/db9f64b3489543b7d16ec930f69c9db34e5b70ae/man/im/menu-display-referents.png -------------------------------------------------------------------------------- /man/im/menu-find.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rswgnu/hyperbole/db9f64b3489543b7d16ec930f69c9db34e5b70ae/man/im/menu-find.png -------------------------------------------------------------------------------- /man/im/menu-hyperbole.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rswgnu/hyperbole/db9f64b3489543b7d16ec930f69c9db34e5b70ae/man/im/menu-hyperbole.png -------------------------------------------------------------------------------- /man/im/menu-key-bindings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rswgnu/hyperbole/db9f64b3489543b7d16ec930f69c9db34e5b70ae/man/im/menu-key-bindings.png -------------------------------------------------------------------------------- /man/im/menu-koutline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rswgnu/hyperbole/db9f64b3489543b7d16ec930f69c9db34e5b70ae/man/im/menu-koutline.png -------------------------------------------------------------------------------- /man/im/menu-rolo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rswgnu/hyperbole/db9f64b3489543b7d16ec930f69c9db34e5b70ae/man/im/menu-rolo.png -------------------------------------------------------------------------------- /man/im/menu-url-browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rswgnu/hyperbole/db9f64b3489543b7d16ec930f69c9db34e5b70ae/man/im/menu-url-browser.png -------------------------------------------------------------------------------- /man/im/menu-web-search-browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rswgnu/hyperbole/db9f64b3489543b7d16ec930f69c9db34e5b70ae/man/im/menu-web-search-browser.png -------------------------------------------------------------------------------- /man/im/wgrid-2x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rswgnu/hyperbole/db9f64b3489543b7d16ec930f69c9db34e5b70ae/man/im/wgrid-2x2.png -------------------------------------------------------------------------------- /man/im/wgrid-2x3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rswgnu/hyperbole/db9f64b3489543b7d16ec930f69c9db34e5b70ae/man/im/wgrid-2x3.png -------------------------------------------------------------------------------- /man/im/wgrid-3x5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rswgnu/hyperbole/db9f64b3489543b7d16ec930f69c9db34e5b70ae/man/im/wgrid-3x5.png -------------------------------------------------------------------------------- /man/im/wgrid-4x6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rswgnu/hyperbole/db9f64b3489543b7d16ec930f69c9db34e5b70ae/man/im/wgrid-4x6.png -------------------------------------------------------------------------------- /man/texinfo-7.css: -------------------------------------------------------------------------------- 1 | /* 2 | Custom CSS for HTML documents generated with Texinfo 7.x's makeinfo. 3 | Public domain 2023 Luis Felipe López Acevedo. All rights waived. 4 | */ 5 | 6 | 7 | /* VARIABLES */ 8 | :root { 9 | color-scheme: light dark; 10 | /* Colors */ 11 | --bg-color: #F0F0F0; 12 | --border-color: silver; 13 | --link-color: #245C8A; 14 | --sheet-color: white; 15 | --sheet-shadow: gray; 16 | --symbol-color: saddlebrown; 17 | --text-color: #333; 18 | /* Fonts */ 19 | --base-font-size: 16px; 20 | } 21 | 22 | @media (prefers-color-scheme: dark) { 23 | :root { 24 | --bg-color: #191919; 25 | --border-color: black; 26 | --link-color: #8EB2CD; 27 | --sheet-color: #222; 28 | --sheet-shadow: var(--border-color); 29 | --symbol-color: darkkhaki; 30 | --text-color: #F5F5F5; 31 | } 32 | } 33 | /* END VARIABLES */ 34 | 35 | 36 | 37 | /* NATIVE ELEMENTS */ 38 | a:link, 39 | a:visited { 40 | color: var(--link-color); 41 | text-decoration: none; 42 | } 43 | 44 | a:active, 45 | a:focus, 46 | a:hover { 47 | text-decoration: underline; 48 | } 49 | 50 | abbr, 51 | acronym { 52 | cursor: help; 53 | } 54 | 55 | blockquote { 56 | border-color: var(--text-color); 57 | border-style: none none none solid; 58 | border-width: 0.5em; 59 | margin-left: 0em; 60 | padding-left: 1.5em; 61 | } 62 | 63 | body { 64 | background-color: var(--sheet-color); 65 | box-shadow: 0 0 2px var(--sheet-shadow); 66 | box-sizing: border-box; 67 | color: var(--text-color); 68 | font-family: sans-serif; 69 | font-size: var(--base-font-size); 70 | margin: 50px auto; 71 | max-width: 960px; 72 | padding: 50px; 73 | } 74 | 75 | code, 76 | samp, 77 | tt, 78 | var { 79 | color: var(--symbol-color); 80 | } 81 | 82 | div.example, 83 | div.lisp { 84 | margin: 0px; 85 | } 86 | 87 | dl { 88 | margin: 3em 0em; 89 | } 90 | 91 | dl dl { 92 | margin: 0em; 93 | } 94 | 95 | dt { 96 | background-color: var(--bg-color); 97 | padding: 0.5em; 98 | } 99 | 100 | dd dt { 101 | background-color: transparent; 102 | border-color: var(--border-color); 103 | border-style: none none none dotted; 104 | border-width: 0.5em; 105 | padding: 0.5em; 106 | } 107 | 108 | h1, 109 | h2, 110 | h2.contents-heading, 111 | h3, 112 | h4 { 113 | padding: 20px 0px 0px 0px; 114 | font-weight: normal; 115 | } 116 | 117 | h1 { 118 | font-size: 2.4em; 119 | } 120 | 121 | h2 { 122 | font-size: 2.2em; 123 | font-weight: bold; 124 | } 125 | 126 | h3 { 127 | font-size: 1.8em; 128 | } 129 | 130 | h4 { 131 | font-size: 1.4em; 132 | } 133 | 134 | hr { 135 | background-color: var(--border-color); 136 | border-style: none; 137 | height: 1px; 138 | margin: 0px; 139 | } 140 | 141 | html { 142 | background-color: var(--bg-color); 143 | } 144 | 145 | img { 146 | max-width: 100%; 147 | } 148 | 149 | li { 150 | padding: 5px; 151 | } 152 | 153 | pre.display, 154 | pre.example-preformatted, 155 | pre.format, 156 | pre.lisp-preformatted, 157 | pre.verbatim{ 158 | overflow: auto; 159 | } 160 | 161 | pre.example-preformatted, 162 | pre.lisp-preformatted, 163 | pre.verbatim { 164 | background-color: #2D3743; 165 | border-color: black; 166 | border-style: solid; 167 | border-width: thin; 168 | color: #E1E1E1; 169 | font-size: smaller; 170 | padding: 1em; 171 | } 172 | 173 | pre.menu-comment-preformatted { 174 | border-color: var(--bg-color); 175 | border-bottom-style: solid; 176 | border-width: thin; 177 | font-family: sans; 178 | } 179 | 180 | strong.def-name { 181 | font-size: var(--base-font-size); 182 | } 183 | 184 | table { 185 | border-collapse: collapse; 186 | margin: 40px 0px; 187 | } 188 | 189 | table.cp-entries-printindex *, 190 | table.fn-entries-printindex *, 191 | table.ky-entries-printindex *, 192 | table.pg-entries-printindex *, 193 | table.tp-entries-printindex *, 194 | table.vr-entries-printindex * { 195 | background-color: inherit; 196 | border-style: none; 197 | } 198 | 199 | td, 200 | th { 201 | border-color: var(--border-color); 202 | border-style: solid; 203 | border-width: thin; 204 | padding: 10px; 205 | } 206 | 207 | th { 208 | background-color: var(--bg-color); 209 | } 210 | /* END NATIVE ELEMENTS */ 211 | 212 | 213 | 214 | /* CLASSES */ 215 | .contents { 216 | margin-bottom: 4em; 217 | } 218 | 219 | .def-type { 220 | color: var(--text-color); 221 | } 222 | 223 | .def-var-arguments { 224 | color: var(--text-color); 225 | } 226 | 227 | .float { 228 | margin: 3em 0em; 229 | } 230 | 231 | .caption { 232 | font-size: smaller; 233 | text-align: center; 234 | } 235 | 236 | .float > img { 237 | display: block; 238 | margin: auto; 239 | } 240 | 241 | .footnote { 242 | font-size: smaller; 243 | margin: 5em 0em; 244 | } 245 | 246 | .footnote h3 { 247 | display: inline; 248 | font-size: small; 249 | } 250 | 251 | .key { 252 | color: var(--symbol-color); 253 | } 254 | 255 | .menu * { 256 | border-style: none; 257 | } 258 | 259 | .menu td { 260 | padding: 0.5em 0em; 261 | } 262 | 263 | .menu td:last-child { 264 | width: 60%; 265 | } 266 | 267 | .menu th { 268 | background-color: inherit; 269 | } 270 | 271 | .nav-panel { 272 | background-color: var(--bg-color); 273 | font-size: small; 274 | padding: 0.2em 1em; 275 | } 276 | /* END CLASSES */ 277 | -------------------------------------------------------------------------------- /smart-clib-sym: -------------------------------------------------------------------------------- 1 | #!/bin/csh -f 2 | # 3 | # Summary: Test whether symbol appears within a set of C libraries. 4 | # Usage: 5 | # 6 | # Author: Bob Weiner 7 | # 8 | # Orig-Date: 5-Oct-91 at 03:29:05 9 | # Last-Mod: 24-Jan-22 at 00:52:07 by Bob Weiner 10 | # 11 | # Copyright (C) 1991-2016 Free Software Foundation, Inc. 12 | # See the "HY-COPY" file for license information. 13 | # 14 | # This file is part of GNU Hyperbole. 15 | # 16 | # Commentary: 17 | # 18 | # Create the file given by the variable 'clib_list' below, and place in that 19 | # file the full path for each C, C++ or Objective-C library that you want 20 | # scanned for symbol names. One filename per line. Do not quote the 21 | # filenames. 22 | # 23 | # Handles exact name matches only. Echos and exits with same output value. 24 | # Either 1 if symbol is found or 0 if not. 25 | 26 | # Code: 27 | 28 | # Create this file and place in the file the full path for each C, C++ or 29 | # Objective-C library that you want scanned for symbol names. One filename 30 | # per line. Do not quote the filenames. 31 | # 32 | set clib_list = "~/.CLIBS-LIST" 33 | 34 | 35 | # This file will automatically be created to cache the symbol names. 36 | # Remove it if you ever want to rebuild the symbol table. 37 | # 38 | set clib_symbols = "~/.clibs-symbols" 39 | 40 | set st = 0 rebuild = 0 41 | if (-e $clib_list) then 42 | if (! -e $clib_symbols || -z $clib_symbols) set rebuild = 1 43 | if ($rebuild || (-M $clib_list) > (-M $clib_symbols)) then 44 | nm -g `cat $clib_list` | grep '^[0-9 ].* _[A-Za-z]' | sed -e 's/^[^_][^_]*_//g' | sort | uniq > $clib_symbols 45 | endif 46 | fgrep -sx $1 $clib_symbols >& /dev/null 47 | @ st = ! $status 48 | endif 49 | 50 | echo $st 51 | exit $st 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /test/MANIFEST: -------------------------------------------------------------------------------- 1 | --- HYPERBOLE TEST CASES --- 2 | demo-tests.el - unit tests from examples in the DEMO 3 | hact-tests.el - hact unit tests 4 | hactypes-tests.el - Ert tests for hactypes 5 | hargs-tests.el - hargs unit tests 6 | hbut-tests.el - hbut unit tests 7 | hib-kbd-tests.el - unit test for hib-kbd 8 | hib-social-tests.el - Test for hib-social 9 | hibtypes-tests.el - unit test for hib-kbd 10 | hmouse-drv-tests.el - hmouse-drv unit tests 11 | hmouse-info-tests.el - hmouse-info unit tests 12 | hpath-tests.el - unit tests for hpath 13 | hsettings-test.el - unit tests for hsettings 14 | hsys-org-tests.el - hsys-org tests 15 | hui-mini-tests.el - hui-mini tests 16 | hui-mouse-tests.el - hui-mouse and hkey-alist Action Key tests 17 | hui-register-tests.el - test for hui-register 18 | hui-select-tests.el - hui-select tests 19 | hui-tests.el - tests for hui.el Hyperbole UI 20 | hy-test-coverage.el - provide test coverage information 21 | hy-test-dependencies.el - Hyperbole test dependencies 22 | hy-test-helpers.el - unit test helpers 23 | hycontrol-tests.el - hycontrol unit tests 24 | hypb-tests.el - tests for hypb.el utility functions 25 | hyperbole-tests.el - tests for hyperbole.el 26 | hyrolo-tests.el - unit tests for hyrolo.el 27 | hywconfig-tests.el - tests for hyperbole window configuration management 28 | kcell-tests.el - test for kcells in Koutlines 29 | kexport-tests.el - test exporting Koutlines to file types 30 | kimport-tests.el - test importing file types to Koutlines 31 | kotl-mode-tests.el - kotl-mode-el tests 32 | kotl-orgtbl-tests.el - kotl orgtbl tests 33 | set-tests.el - mathematical set library tests 34 | smart-org-tests.el - smart-org-el tests 35 | test-helpers-tests.el - unit test of the test helpers 36 | 37 | --- HYPERBOLE TEST RESOURCES --- 38 | hibtypes-resources - test resources for hibtypes-tests 39 | hmouse-drv-resources - test resources for hmouse-drv-tests 40 | -------------------------------------------------------------------------------- /test/hact-tests.el: -------------------------------------------------------------------------------- 1 | ;;; hact-tests.el --- unit tests for hact -*- lexical-binding: t; -*- 2 | ;; 3 | ;; Author: Mats Lidell 4 | ;; 5 | ;; Orig-Date: 16-May-24 at 00:29:22 6 | ;; Last-Mod: 22-Feb-25 at 09:35:56 by Bob Weiner 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 2021-2022 Free Software Foundation, Inc. 11 | ;; See the "HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | 15 | ;;; Commentary: 16 | ;; 17 | 18 | ;;; Code: 19 | 20 | (require 'ert) 21 | (require 'hact) 22 | 23 | (ert-deftest hact-tests--action-params-with-lambdas () 24 | "Lambda used with `action:params' should return the lambda parameters." 25 | (should (equal nil (action:params (lambda () nil)))) 26 | (should (equal '(_x) (action:params (lambda (_x) nil)))) 27 | (should (equal '(_x _y) (action:params (lambda (_x _y) nil))))) 28 | 29 | (ert-deftest hact-tests--actype-act-with-lambdas () 30 | "Lambda with `actype:act' should work over versions of Emacs. 31 | Covers backwards incompatible change in Emacs 30." 32 | (should (= 2 (actype:act (lambda () 2)))) 33 | (should (= 2 (actype:act (lambda (x) x) 2))) 34 | (should (= 2 (actype:act (lambda (x) (1+ x)) 1))) 35 | (should (= 2 (actype:act (lambda (x y) (+ x y)) 1 1)))) 36 | 37 | (provide 'hact-tests) 38 | ;;; hact-tests.el ends here 39 | -------------------------------------------------------------------------------- /test/hactypes-tests.el: -------------------------------------------------------------------------------- 1 | ;;; hactypes-test.el -- Ert tests for hactypes -*- lexical-binding: t; -*- 2 | ;; 3 | ;; Author: Mats Lidell 4 | ;; 5 | ;; Orig-Date: 30-Jan-21 at 12:00:00 6 | ;; Last-Mod: 1-Jun-25 at 23:31:35 by Mats Lidell 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 2021 Free Software Foundation, Inc. 11 | ;; See the "HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | 15 | ;;; Commentary: 16 | 17 | ;; 18 | 19 | ;;; Code: 20 | 21 | (require 'ert) 22 | (require 'ert-x) 23 | (require 'el-mock) 24 | (require 'hactypes) 25 | (require 'hy-test-helpers "test/hy-test-helpers") 26 | 27 | (ert-deftest display-boolean-true-test () 28 | (ert-with-message-capture cap 29 | (should (actypes::display-boolean t)) 30 | (hy-test-helpers:should-last-message "Result = t; Boolean value = True" cap))) 31 | 32 | (ert-deftest display-boolean-false-test () 33 | (ert-with-message-capture cap 34 | (should (actypes::display-boolean nil)) 35 | (hy-test-helpers:should-last-message "Result = nil; Boolean value = False" cap))) 36 | 37 | (ert-deftest hactypes-tests--link-to-Info-index-item () 38 | "Verify `actypes::link-to-Info-index-item'." 39 | (should-error (actypes::link-to-Info-index-item "wrong-format") :type 'error) 40 | (should-error (actypes::link-to-Info-index-item "(unknown-file)unknown-index-item") :type 'error) 41 | (mocklet (((id-info-item "(infofile)index-item") => t)) 42 | (actypes::link-to-Info-index-item "(infofile)index-item")) 43 | (unwind-protect 44 | (progn 45 | (actypes::link-to-Info-index-item "(hyperbole)hyperb:dir") 46 | (should (string-prefix-p "*info*" (buffer-name))) 47 | (should (string= "hyperbole" (file-name-nondirectory Info-current-file))) 48 | (should (string= "Documentation" Info-current-node)) 49 | (should (looking-at-p "The Hyperbole Manual is a reference manual, not a simple introduction\\."))) 50 | (kill-matching-buffers "^\\*info\\*" nil t))) 51 | 52 | (provide 'hactypes-tests) 53 | 54 | ;; This file can't be byte-compiled without the `el-mock' package 55 | ;; which is not a dependency of Hyperbole. 56 | ;; 57 | ;; Local Variables: 58 | ;; no-byte-compile: t 59 | ;; End: 60 | 61 | ;;; hactypes-tests.el ends here 62 | -------------------------------------------------------------------------------- /test/hargs-tests.el: -------------------------------------------------------------------------------- 1 | ;;; hargs-tests.el --- Tests for hargs.el -*- lexical-binding: t; -*- 2 | ;; 3 | ;; Author: Mats Lidell 4 | ;; 5 | ;; Orig-Date: 04-Feb-22 at 23:00:00 6 | ;; Last-Mod: 2-Jun-25 at 23:48:30 by Bob Weiner 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 2022 Free Software Foundation, Inc. 11 | ;; See the "HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | 15 | ;;; Commentary: 16 | ;; 17 | ;; Tests for "../hargs.el" 18 | 19 | ;;; Code: 20 | 21 | (require 'ert) 22 | (require 'ert-x) 23 | (require 'hargs) 24 | (require 'hy-test-helpers "test/hy-test-helpers") 25 | 26 | (ert-deftest hargs-get-verify-extension-characters () 27 | "Verify hyperbole extension characters are indentified." 28 | (skip-unless (not noninteractive)) 29 | (let ((file (make-temp-file "hypb"))) 30 | (unwind-protect 31 | (progn 32 | (ert-simulate-keys "xyz\r" 33 | (should (string= (hargs:get "+I: ") "xyz"))) 34 | (ert-simulate-keys "xyz\r" 35 | (should (string= (hargs:get "+L: ") "xyz"))) 36 | (ert-simulate-keys (concat "(\"xyz\" \"" file "\")\r") 37 | (should (equal (hargs:get "+M: ") (list "xyz" file)))) 38 | (ert-simulate-keys "xyz\r" 39 | (should (string= (hargs:get "+V: ") "xyz"))) 40 | (ert-simulate-keys "xyz\r" 41 | (should (string= (hargs:get "+X: ") "(dir)xyz"))) 42 | (should-error (hargs:get "+A: ") :type 'error)) 43 | (hy-delete-file-and-buffer file)))) 44 | 45 | (ert-deftest hargs-get-verify-extension-characters-+K () 46 | "Verify hyperbole extension character +K is indentified." 47 | (cl-letf (((symbol-function 'hargs:read) (lambda (_prompt &optional _a _b _c _d) "xyz"))) 48 | (should (string= (hargs:get "+K: ") "xyz")))) 49 | 50 | (ert-deftest hargs-tests--sexpression-p () 51 | "Verify behavior of `hargs:sexpression-p'." 52 | (with-temp-buffer 53 | (insert " (setq var (+ 1 2)) ") 54 | ;; pos ->123456789012345678901 55 | (dolist (v '((1 nil nil) 56 | (2 "(setq var (+ 1 2))" "(setq var (+ 1 2))") 57 | (3 "(setq var (+ 1 2))" nil) 58 | (4 "(setq var (+ 1 2))" nil) 59 | (11 "(setq var (+ 1 2))" nil) 60 | (12 "(+ 1 2)" "(+ 1 2)") 61 | (13 "(+ 1 2)" nil) 62 | (18 "(+ 1 2)" nil) 63 | (19 "(+ 1 2)" "(+ 1 2)") 64 | (20 "(setq var (+ 1 2))" "(setq var (+ 1 2))") 65 | (21 nil nil))) 66 | (goto-char (car v)) 67 | (should (string= (cadr v) (hargs:sexpression-p))) 68 | (should (string= (caddr v) (hargs:sexpression-p t)))))) 69 | 70 | (provide 'hargs-tests) 71 | ;;; hargs-tests.el ends here 72 | -------------------------------------------------------------------------------- /test/hib-kbd-tests.el: -------------------------------------------------------------------------------- 1 | ;;; hib-kbd-tests.el --- unit test for hib-kbd -*- lexical-binding: t; -*- 2 | 3 | ;; Author: Mats Lidell 4 | ;; 5 | ;; Orig-Date: 30-Jan-21 at 12:00:00 6 | ;; Last-Mod: 1-Jun-25 at 10:52:33 by Mats Lidell 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 2021-2024 Free Software Foundation, Inc. 11 | ;; See the "HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | 15 | ;;; Commentary: 16 | 17 | ;; Helper functions 18 | 19 | ;;; Code: 20 | 21 | (require 'ert) 22 | (require 'hib-kbd) 23 | (require 'hy-test-helpers "test/hy-test-helpers") 24 | 25 | (declare-function hy-test-helpers:consume-input-events "hy-test-helpers") 26 | 27 | (ert-deftest kbd-key-hy-about-test () 28 | "Test if HY-ABOUT file is displayed properly from the Hyperbole menus." 29 | (skip-unless (not noninteractive)) 30 | (unwind-protect 31 | (progn 32 | (should (hact 'kbd-key "C-h h d a")) 33 | (hy-test-helpers:consume-input-events) 34 | (should (string= (buffer-name (current-buffer)) "HY-ABOUT" ))) 35 | (kill-buffer "HY-ABOUT"))) 36 | 37 | (ert-deftest kbd-key-hy-demo-factorial-test () 38 | "Test if factorial button from DEMO file works properly." 39 | (skip-unless (not noninteractive)) 40 | (unwind-protect 41 | (let ((enable-local-variables nil)) 42 | (should (hact 'kbd-key "C-u C-h h d d")) 43 | (hy-test-helpers:consume-input-events) 44 | (should (string= (buffer-name (current-buffer)) "DEMO")) 45 | (should (hact 'kbd-key "C-h h a factorial RET")) 46 | (hy-test-helpers:consume-input-events)) 47 | (kill-buffer "DEMO"))) 48 | 49 | (provide 'hib-kbd-tests) 50 | ;;; hib-kbd-tests.el ends here 51 | -------------------------------------------------------------------------------- /test/hib-social-tests.el: -------------------------------------------------------------------------------- 1 | ;;; hib-social-tests.el --- Test for hib-social -*- lexical-binding: t; -*- 2 | 3 | ;; Author: Mats Lidell 4 | ;; 5 | ;; Orig-Date: 20-Feb-21 at 23:24:00 6 | ;; Last-Mod: 3-Mar-24 at 11:28:17 by Mats Lidell 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 2021 Free Software Foundation, Inc. 11 | ;; See the "HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | 15 | ;;; Commentary: 16 | 17 | ;; 18 | 19 | ;;; Code: 20 | 21 | (require 'hib-social) 22 | (require 'ert) ;To define `should' earlier. 23 | (require 'el-mock) 24 | (require 'hy-test-helpers) 25 | 26 | ;; Hib-social 27 | (defun hib-social-should-browse-twitter-url (url &optional new-window) 28 | "Verify call with proper URL and optional NEW-WINDOW." 29 | (should (equal url "https://twitter.com/search?q=@fsf")) 30 | (should (equal new-window nil))) 31 | 32 | (ert-deftest hib-social-twitter-test () 33 | (with-temp-buffer 34 | (insert "tw@fsf") 35 | (goto-char 2) 36 | (let ((browse-url-browser-function 'hib-social-should-browse-twitter-url)) 37 | (ibtypes::social-reference)))) 38 | 39 | ;; Github 40 | (defun hib-social-should-browse-github-url (url &optional new-window) 41 | "Verify call with proper URL and optional NEW-WINDOW." 42 | (should (equal url "https://github.com/rswgnu/hyperbole")) 43 | (should (equal new-window nil))) 44 | 45 | (ert-deftest hib-github-user-default-test () 46 | (with-temp-buffer 47 | (insert "gh#/hyperbole") 48 | (goto-char 4) 49 | (let ((browse-url-browser-function 'hib-social-should-browse-github-url) 50 | (hibtypes-github-default-user "rswgnu")) 51 | (ibtypes::social-reference)))) 52 | 53 | (ert-deftest hib-github-ignore-default-test () 54 | (with-temp-buffer 55 | (insert "gh#/rswgnu/hyperbole") 56 | (goto-char 4) 57 | (let ((browse-url-browser-function 'hib-social-should-browse-github-url) 58 | (hibtypes-github-default-user "whatever")) 59 | (ibtypes::social-reference)))) 60 | 61 | (ert-deftest hibtypes-repo-cache-does-not-exist-test () 62 | "Verify cache is rebuild if it does not exist." 63 | (let ((hibtypes-git-repos-cache "not-existing-file")) 64 | (unwind-protect 65 | (mocklet (((hibtypes-git-build-repos-cache t) => t)) 66 | (should (hibtypes-git-build-or-add-to-repos-cache "project"))) 67 | (hy-delete-file-and-buffer hibtypes-git-repos-cache)))) 68 | 69 | (ert-deftest hibtypes-repo-cache-exist-test () 70 | "Verify project is added if cache exist." 71 | (let ((hibtypes-git-repos-cache (make-temp-file "hypb" nil "cache" "cache contents"))) 72 | (unwind-protect 73 | (mocklet (((hibtypes-git-add-project-to-repos-cache "project") => t)) 74 | (should (hibtypes-git-build-or-add-to-repos-cache "project"))) 75 | (hy-delete-file-and-buffer hibtypes-git-repos-cache)))) 76 | 77 | (provide 'hib-social-tests) 78 | 79 | ;; This file can't be byte-compiled without the `el-mock' package 80 | ;; which is not a dependency of Hyperbole. 81 | ;; 82 | ;; Local Variables: 83 | ;; no-byte-compile: t 84 | ;; End: 85 | 86 | ;;; hib-social-tests.el ends here 87 | 88 | -------------------------------------------------------------------------------- /test/hibtypes-resources/TAGS: -------------------------------------------------------------------------------- 1 | 2 | test-data.el,25 3 | (defun test-func 19,386 4 | -------------------------------------------------------------------------------- /test/hibtypes-resources/test-data.el: -------------------------------------------------------------------------------- 1 | ;;; test-data.el 2 | 3 | ;; Author: Mats Lidell 4 | ;; 5 | ;; Orig-Date: 24-Apr-25 at 22:20:39 6 | ;; Last-Mod: 24-Apr-25 at 22:22:16 by Mats Lidell 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 2025 Free Software Foundation, Inc. 11 | ;; See the "HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | 15 | ;;; Commentary: 16 | 17 | ;;; Code: 18 | 19 | (defun test-func () 20 | "Test function." 21 | nil) 22 | -------------------------------------------------------------------------------- /test/hmouse-drv-resources/TAGS: -------------------------------------------------------------------------------- 1 | 2 | test-data.el,25 3 | (defun test-func 19,386 4 | -------------------------------------------------------------------------------- /test/hmouse-drv-resources/test-data.el: -------------------------------------------------------------------------------- 1 | ;;; test-data.el 2 | 3 | ;; Author: Mats Lidell 4 | ;; 5 | ;; Orig-Date: 24-Apr-25 at 22:20:39 6 | ;; Last-Mod: 24-Apr-25 at 22:22:16 by Mats Lidell 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 2025 Free Software Foundation, Inc. 11 | ;; See the "HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | 15 | ;;; Commentary: 16 | 17 | ;;; Code: 18 | 19 | (defun test-func () 20 | "Test function." 21 | nil) 22 | -------------------------------------------------------------------------------- /test/hmouse-info-tests.el: -------------------------------------------------------------------------------- 1 | ;;; hmouse-info-tests.el --- hmouse-info unit tests -*- lexical-binding: t; -*- 2 | 3 | ;; Author: Mats Lidell 4 | ;; 5 | ;; Orig-Date: 29-Dec-21 at 09:02:00 6 | ;; Last-Mod: 25-Apr-25 at 19:56:35 by Mats Lidell 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 2021-2022 Free Software Foundation, Inc. 11 | ;; See the "HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | 15 | ;;; Commentary: 16 | 17 | ;; See "../hmouse-info.el" 18 | 19 | ;;; Code: 20 | 21 | (require 'ert) 22 | (require 'ert-x) 23 | (require 'hmouse-info) 24 | 25 | (ert-deftest hmouse-info-read-index-with-completion () 26 | "Read a completion that completes." 27 | (ert-simulate-keys "(emacs)regex\t\r" 28 | (should (string= "(emacs)regexp" (Info-read-index-item-name "Prompt: "))))) 29 | 30 | (ert-deftest hmouse-info-build-completions-no-match () 31 | "Build completions." 32 | (unwind-protect 33 | (progn 34 | (info "(emacs)") 35 | (setq Info-complete-menu-buffer (clone-buffer)) 36 | (should (eq '() (Info-build-menu-item-completions "nothinglikethis" nil t))) 37 | (kill-buffer "*info*")))) 38 | 39 | (ert-deftest hmouse-info-build-completions-multiple-matches () 40 | "Build completions." 41 | (unwind-protect 42 | (progn 43 | (info "(emacs)") 44 | (setq Info-complete-menu-buffer (clone-buffer)) 45 | (dolist (m (Info-build-menu-item-completions "regexp" nil t)) 46 | (should (string-prefix-p "regexp" m t)))) 47 | (kill-buffer "*info*"))) 48 | 49 | (provide 'hmouse-info-tests) 50 | ;;; hmouse-info-tests.el ends here 51 | -------------------------------------------------------------------------------- /test/hproperty-tests.el: -------------------------------------------------------------------------------- 1 | ;;; hproperty-tests.el --- one line summary -*- lexical-binding: t; -*- 2 | ;; 3 | ;; Author: Mats Lidell 4 | ;; 5 | ;; Orig-Date: 6-Aug-24 at 20:32:51 6 | ;; Last-Mod: 4-Mar-25 at 17:04:46 by Mats Lidell 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 2021-2022 Free Software Foundation, Inc. 11 | ;; See the "HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | 15 | ;;; Commentary: 16 | ;; 17 | 18 | ;;; Code: 19 | 20 | (require 'ert) 21 | (require 'el-mock) 22 | (require 'hproperty) 23 | 24 | (ert-deftest hproperty-tests--but-add () 25 | "Verify `hproperty:but-add'." 26 | (let ((hproperty:but-emphasize-flag t)) 27 | (with-temp-buffer 28 | (insert "1234") 29 | (should (equal 'highlight (hproperty:but-add (point-min) (point-max) hproperty:but-face))) 30 | (goto-char 3) 31 | (should (hproperty:but-p)))) 32 | (let ((hproperty:but-emphasize-flag nil)) 33 | (with-temp-buffer 34 | (insert "1234") 35 | (should-not (hproperty:but-add (point-min) (point-max) hproperty:but-face)) 36 | (goto-char 3) 37 | (should (hproperty:but-p))))) 38 | 39 | (provide 'hproperty-tests) 40 | 41 | ;; This file can't be byte-compiled without the `el-mock' package 42 | ;; which is not a dependency of Hyperbole. 43 | ;; 44 | ;; Local Variables: 45 | ;; no-byte-compile: t 46 | ;; End: 47 | 48 | ;;; hproperty-tests.el ends here 49 | -------------------------------------------------------------------------------- /test/hsettings-test.el: -------------------------------------------------------------------------------- 1 | ;;; hsettings-test.el --- one line summary -*- lexical-binding: t; -*- 2 | ;; 3 | ;; Author: Mats Lidell 4 | ;; 5 | ;; Orig-Date: 20-Jan-24 at 12:28:01 6 | ;; Last-Mod: 12-Mar-24 at 22:59:00 by Mats Lidell 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 2024 Free Software Foundation, Inc. 11 | ;; See the "HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | 15 | ;;; Commentary: 16 | ;; 17 | 18 | ;;; Code: 19 | 20 | (require 'ert) 21 | (require 'el-mock) 22 | (require 'hsettings) 23 | 24 | (ert-deftest hsettings-test--hyperbole-web-search () 25 | "Verify `hyperbole-web-search´." 26 | (mocklet (((browse-url "http://www.google.com/search?q=hyperbole") => "return")) 27 | (should (string= (hyperbole-web-search "google" "hyperbole" nil) "return"))) 28 | (should (string= (hyperbole-web-search "google" "hyperbole" t) 29 | "http://www.google.com/search?q=hyperbole")) 30 | (should-error (hyperbole-web-search "unknown" "hyperbole" nil)) 31 | (should-error (hyperbole-web-search "unknown" "hyperbole" t)) 32 | 33 | ;; Jump 34 | (mocklet (((webjump) => "return")) 35 | (should (string= (hyperbole-web-search "Jump" "arg" nil) "return"))) 36 | (should (equal (hyperbole-web-search "Jump" "arg" t) '(webjump)))) 37 | 38 | (provide 'hsettings-test) 39 | 40 | ;; This file can't be byte-compiled without the `el-mock' package 41 | ;; which is not a dependency of Hyperbole. 42 | ;; 43 | ;; Local Variables: 44 | ;; no-byte-compile: t 45 | ;; End: 46 | 47 | ;;; hsettings-test.el ends here 48 | -------------------------------------------------------------------------------- /test/hui-mini-tests.el: -------------------------------------------------------------------------------- 1 | ;;; hui-mini-tests.el --- Unit test for hui-mini -*- lexical-binding: t; -*- 2 | ;; 3 | ;; Author: Mats Lidell 4 | ;; 5 | ;; Orig-Date: 30-Jan-25 at 22:39:37 6 | ;; Last-Mod: 4-Mar-25 at 17:06:50 by Mats Lidell 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 2025 Free Software Foundation, Inc. 11 | ;; See the "HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | 15 | ;;; Commentary: 16 | ;; 17 | 18 | ;;; Code: 19 | 20 | (require 'hui-mini) 21 | (require 'ert) 22 | (require 'el-mock) 23 | 24 | (ert-deftest hui--menu-read-from-minibuffer () 25 | "Verify prompt shows proper active selection." 26 | (defvar menu-string) 27 | (dolist (v '((nil "None") 28 | (:buttons "Hyperbole-Buttons-Only") 29 | (t "All-Hyperbole-Contexts"))) 30 | (let ((hsys-org-enable-smart-keys (car v)) 31 | (menu-string (cadr v))) 32 | (mocklet (((read-from-minibuffer "" (format "Org M-RET ==%s==" menu-string) hui:menu-mode-map nil t nil nil) => t)) 33 | (should (hui:menu-read-from-minibuffer "" (format "Org M-RET %s" menu-string) hui:menu-mode-map nil t)))))) 34 | 35 | (provide 'hui-mini-tests) 36 | 37 | ;; This file can't be byte-compiled without the `el-mock' package 38 | ;; which is not a dependency of Hyperbole. 39 | ;; 40 | ;; Local Variables: 41 | ;; no-byte-compile: t 42 | ;; End: 43 | 44 | ;;; hui-mini-tests.el ends here 45 | -------------------------------------------------------------------------------- /test/hui-register-tests.el: -------------------------------------------------------------------------------- 1 | ;;; hui-register-tests.el --- test for hui-register -*- lexical-binding: t; -*- 2 | ;; 3 | ;; Author: Mats Lidell 4 | ;; 5 | ;; Orig-Date: 10-Sep-22 at 20:43:17 6 | ;; Last-Mod: 22-Feb-24 at 00:00:12 by Mats Lidell 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 2021-2022 Free Software Foundation, Inc. 11 | ;; See the "HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | 15 | ;;; Commentary: 16 | ;; 17 | 18 | ;;; Code: 19 | 20 | (require 'ert) 21 | (require 'hmouse-drv) 22 | (require 'hui-register) 23 | (require 'hy-test-helpers "test/hy-test-helpers") 24 | 25 | (ert-deftest hui-register-test--create-register-content () 26 | "Verify the struct contains its parts." 27 | (let ((file (make-temp-file "hypb"))) 28 | (unwind-protect 29 | (progn 30 | (find-file file) 31 | (insert "<[label label]> $HOME") 32 | (goto-char 5) 33 | (let ((content (hui-register-struct-at-point))) 34 | (should (equal (hui-register-but-label content) "label_label")) 35 | (should (equal (hui-register-but-link content) 'link-to-ibut)) 36 | (should (markerp (hui-register-but-mpos content))) 37 | (should (equal (marker-buffer (hui-register-but-mpos content)) (current-buffer))) 38 | (should (equal (hui-register-but-file content) (hypb:buffer-file-name))))) 39 | (hy-delete-file-and-buffer file)))) 40 | 41 | (ert-deftest hui-register-test--register-val-jump-to () 42 | "Verify register val jumps to right file." 43 | (let ((file (make-temp-file "hypb"))) 44 | (unwind-protect 45 | (progn 46 | (find-file file) 47 | (insert "<[label]> $HOME") 48 | (goto-char 5) 49 | (let ((content (hui-register-struct-at-point)) 50 | (pos (point))) 51 | (set-buffer "*scratch*") 52 | (should (equal (buffer-name) "*scratch*")) 53 | (register-val-jump-to content nil) 54 | (should (equal (hypb:buffer-file-name) file)) 55 | (should (equal pos (point))))) 56 | (hy-delete-file-and-buffer file)))) 57 | 58 | (ert-deftest hui-register-test--register-val-insert-ibut () 59 | "Verify register val inserts ibut." 60 | (let ((file1 (make-temp-file "hypb")) 61 | (file2 (make-temp-file "hypb"))) 62 | (unwind-protect 63 | (progn 64 | (find-file file1) 65 | (insert "<[label]> ${HOME}") 66 | (goto-char 5) 67 | (let ((content (hui-register-struct-at-point))) 68 | (find-file file2) 69 | ;; Inserts ebut into file2 that contains an ilink in file1 70 | ;; that jumps to ${HOME} 71 | (register-val-insert content) 72 | (should (equal (hypb:buffer-file-name) file2)) 73 | (goto-char 5) 74 | (should (ebut:at-p)) 75 | (action-key) 76 | (should (equal (expand-file-name default-directory) 77 | (file-name-as-directory (getenv "HOME")))))) 78 | (hy-delete-file-and-buffer file1) 79 | (hy-delete-file-and-buffer file2)))) 80 | 81 | (ert-deftest hui-register-test--register-val-insert-ebut () 82 | "Verify register val inserts link to ebut." 83 | (let ((file1 (make-temp-file "hypb")) 84 | (file2 (make-temp-file "hypb"))) 85 | (unwind-protect 86 | (progn 87 | (find-file file1) 88 | (ebut:program "label" 'link-to-directory "/tmp") 89 | (goto-char 5) 90 | (let ((content (hui-register-struct-at-point))) 91 | (find-file file2) 92 | (register-val-insert content) 93 | (should (equal (hypb:buffer-file-name) file2)) 94 | (goto-char 5) 95 | (should (ebut:at-p)) 96 | (action-key) 97 | (should (equal major-mode 'dired-mode)) 98 | ;; Support c:/tmp on Windows too 99 | (should (member default-directory (list (expand-file-name "tmp/" "/") 100 | "/private/tmp/"))))) 101 | (hy-delete-file-and-buffer file1) 102 | (hy-delete-file-and-buffer file2)))) 103 | 104 | (provide 'hui-register-tests) 105 | ;;; hui-register-tests.el ends here 106 | -------------------------------------------------------------------------------- /test/hui-select-tests.el: -------------------------------------------------------------------------------- 1 | ;;; hui-select-tests.el --- Unit tests -*- lexical-binding: t; -*- 2 | 3 | ;; Author: Mats Lidell 4 | ;; 5 | ;; Orig-Date: 14-Apr-22 at 23:45:52 6 | ;; Last-Mod: 1-Jun-25 at 23:40:09 by Mats Lidell 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 2021-2024 Free Software Foundation, Inc. 11 | ;; See the "../HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of Hyperbole. 14 | ;; 15 | ;;; Commentary: 16 | ;; 17 | ;; Unit tests for "../hui-select.el" 18 | 19 | ;;; Code: 20 | 21 | ;; 22 | ;;; ************************************************************************ 23 | ;;; Tests 24 | ;;; ************************************************************************ 25 | 26 | (require 'ert) 27 | (require 'ert-x) 28 | (require 'hui-select) 29 | (require 'hy-test-helpers "test/hy-test-helpers") 30 | 31 | (ert-deftest hui-select--at-delimited-thing-p () 32 | "At delimited thing p returns type of thing." 33 | (with-temp-buffer 34 | (insert "(\"x\") ") 35 | 36 | ;; hui-select-sexp-start 37 | (goto-char 1) 38 | (should (equal (hui-select-at-delimited-thing-p) 'hui-select-sexp-start)) 39 | 40 | ;; hui-select-string 41 | (goto-char 2) 42 | (should (equal (hui-select-at-delimited-thing-p) 'hui-select-string)) 43 | 44 | ;; nil 45 | (goto-char 3) 46 | (should-not (hui-select-at-delimited-thing-p)) 47 | 48 | ;; hui-select-string 49 | (goto-char 4) 50 | (should (equal (hui-select-at-delimited-thing-p) 'hui-select-string)) 51 | 52 | ;; hui-select-sexp-end 53 | (goto-char 5) 54 | (should (equal (hui-select-at-delimited-thing-p) 'hui-select-sexp-end)))) 55 | 56 | (ert-deftest hui-select--delimited-thing () 57 | "Delimited thing marks region of thing." 58 | (with-temp-buffer 59 | (insert "(\"x\") ") 60 | 61 | ;; hui-select-sexp-start 62 | (goto-char 1) 63 | (should (hui-select-delimited-thing)) 64 | (should (string= (buffer-substring-no-properties (region-beginning) (region-end)) "(\"x\")")) 65 | 66 | ;; hui-select-string 67 | (goto-char 2) 68 | (should (hui-select-delimited-thing)) 69 | (should (string= (buffer-substring-no-properties (region-beginning) (region-end)) "\"x\"")))) 70 | 71 | 72 | (ert-deftest hui-select--delimited-thing-ending-in-newline () 73 | "Delimited thing marks region of thing when next char after things is a newline." 74 | (with-temp-buffer 75 | (insert "(\"x\")\n") 76 | 77 | ;; hui-select-sexp-start 78 | (goto-char 1) 79 | (should (hui-select-delimited-thing)) 80 | (should (string= (buffer-substring-no-properties (region-beginning) (region-end)) "(\"x\")\n")))) 81 | 82 | (ert-deftest hui-select--thing () 83 | "`hui-select-thing' selects bigger sections of text when called repeatedly." 84 | (skip-unless (not noninteractive)) 85 | (hui-select-reset) 86 | (with-temp-buffer 87 | (insert "Buffer\n\nParagraph\nline. One word.") 88 | (forward-char -3) 89 | 90 | ;; word 91 | (should (hui-select-thing)) 92 | (should (string= (buffer-substring-no-properties (region-beginning) (region-end)) 93 | "word")) 94 | 95 | ;; symbol 96 | (should (hui-select-thing)) 97 | (should (string= (buffer-substring-no-properties (region-beginning) (region-end)) 98 | "word.")) 99 | 100 | ;; sentence 101 | (should (hui-select-thing)) 102 | (should (string= (buffer-substring-no-properties (region-beginning) (region-end)) 103 | "One word.")) 104 | 105 | ;; line 106 | (should (hui-select-thing)) 107 | (should (string= (buffer-substring-no-properties (region-beginning) (region-end)) 108 | "line. One word.")) 109 | 110 | ;; paragraph 111 | (should (hui-select-thing)) 112 | (should (string= (buffer-substring-no-properties (region-beginning) (region-end)) 113 | "\nParagraph\nline. One word.")) 114 | 115 | ;; buffer 116 | (should (hui-select-thing)) 117 | (should (string= (buffer-substring-no-properties (region-beginning) (region-end)) 118 | "Buffer\n\nParagraph\nline. One word.")) 119 | 120 | ;; error 121 | (ert-with-message-capture cap 122 | (should-not (hui-select-thing)) 123 | (hy-test-helpers:should-last-message "(hui-select-boundaries): ‘buffer’ is the largest selectable region" cap)))) 124 | 125 | (ert-deftest hui-select--thing-interactive-prints-type-of-match () 126 | "`hui-select-thing' selects bigger sections of text when called repeatedly. 127 | Verifies right type of match is printed when `hui-select-display-type' is set to t." 128 | (skip-unless (not noninteractive)) 129 | (let ((hui-select-display-type t)) 130 | (hui-select-reset) 131 | (with-temp-buffer 132 | (insert "Buffer\n\nParagraph\nline. One word.") 133 | (forward-char -3) 134 | 135 | (ert-with-message-capture cap 136 | (should (call-interactively 'hui-select-thing)) 137 | (hy-test-helpers:should-last-message "word" cap)) 138 | (should (string= (buffer-substring-no-properties (region-beginning) (region-end)) "word")) 139 | 140 | (ert-with-message-capture cap 141 | (should (call-interactively 'hui-select-thing)) 142 | (hy-test-helpers:should-last-message "symbol" cap)) 143 | (should (string= (buffer-substring-no-properties (region-beginning) (region-end)) "word.")) 144 | 145 | (ert-with-message-capture cap 146 | (should (call-interactively 'hui-select-thing)) 147 | (hy-test-helpers:should-last-message "sentence" cap)) 148 | (should (string= (buffer-substring-no-properties (region-beginning) (region-end)) "One word.")) 149 | 150 | (ert-with-message-capture cap 151 | (should (call-interactively 'hui-select-thing)) 152 | (hy-test-helpers:should-last-message "line" cap)) 153 | (should (string= (buffer-substring-no-properties (region-beginning) (region-end)) 154 | "line. One word.")) 155 | 156 | (ert-with-message-capture cap 157 | (should (call-interactively 'hui-select-thing)) 158 | (hy-test-helpers:should-last-message "paragraph" cap)) 159 | (should (string= (buffer-substring-no-properties (region-beginning) (region-end)) 160 | "\nParagraph\nline. One word.")) 161 | 162 | (ert-with-message-capture cap 163 | (should (call-interactively 'hui-select-thing)) 164 | (hy-test-helpers:should-last-message "buffer" cap)) 165 | (should (string= (buffer-substring-no-properties (region-beginning) (region-end)) 166 | "Buffer\n\nParagraph\nline. One word.")) 167 | 168 | (ert-with-message-capture cap 169 | (should-not (call-interactively 'hui-select-thing)) 170 | (hy-test-helpers:should-last-message "(hui-select-boundaries): ‘buffer’ is the largest selectable region" cap))))) 171 | 172 | (provide 'hui-select-tests) 173 | ;;; hui-select-tests.el ends here 174 | -------------------------------------------------------------------------------- /test/hy-test-coverage.el: -------------------------------------------------------------------------------- 1 | ;;; hy-test-coverage.el --- support for test coverage -*- lexical-binding: t; -*- 2 | ;; 3 | ;; Author: Mats Lidell 4 | ;; 5 | ;; Orig-Date: 21-Mar-24 at 13:22:27 6 | ;; Last-Mod: 7-Apr-24 at 10:43:42 by Bob Weiner 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 2024 Free Software Foundation, Inc. 11 | ;; See the "HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | 15 | ;;; Commentary: 16 | ;; 17 | ;; Uses the testcover functionality and runs a specified test 18 | ;; suite for a file that is monitored for coverage. See 19 | ;; "testcover.el" for how to interpret the "splotches", the color code 20 | ;; characters in the monitored filed. 21 | ;; 22 | ;; See also "../Makefile#coverage:", a make target for running from the 23 | ;; command line. 24 | 25 | ;;; Code: 26 | 27 | (require 'hypb-ert) 28 | (require 'testcover) 29 | 30 | (defun hy-test--count-coverage () 31 | "Count coverage splotches." 32 | (cl-count-if 33 | (lambda (x) 34 | (string-prefix-p "testcover-" (symbol-name (overlay-get x 'face)))) 35 | (car (overlay-lists)))) 36 | 37 | (defun hy-test-coverage-file (filename &optional testspec) 38 | "In FILENAME, run TESTSPEC and produce coverage data. 39 | With no TESTSPEC all tests are run." 40 | (interactive "fFilename: \nsTestspec: ") 41 | (unless (file-exists-p filename) 42 | (error "(hy-test-coverage-file): File %s does not exist" filename)) 43 | (unless testspec 44 | (setq testspec t)) 45 | (let ((buff (find-file filename))) 46 | (testcover-unmark-all buff) 47 | (hypb-ert-require-libraries) 48 | (testcover-start filename) 49 | (bury-buffer) 50 | (ert testspec) 51 | (testcover-mark-all buff) 52 | (message "Number of splotches %d." (hy-test--count-coverage)) 53 | (switch-to-buffer buff) 54 | (point-min))) 55 | 56 | (provide 'hy-test-coverage) 57 | ;;; hy-test-coverage.el ends here 58 | -------------------------------------------------------------------------------- /test/hy-test-dependencies.el: -------------------------------------------------------------------------------- 1 | ;;; hy-test-dependencies.el --- Hyperbole test dependencies -*- lexical-binding: t; -*- 2 | 3 | ;; Author: Mats Lidell 4 | ;; 5 | ;; Orig-Date: 20-Feb-21 at 23:16:00 6 | ;; Last-Mod: 25-Apr-25 at 19:28:36 by Mats Lidell 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 2021-2024 Free Software Foundation, Inc. 11 | ;; See the "HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | 15 | ;;; Commentary: 16 | ;; 17 | ;; Load prerequisites for running the tests. 18 | 19 | ;;; Code: 20 | 21 | (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/")) 22 | (package-initialize) 23 | 24 | (require 'hload-path) 25 | (require 'hyperbole) 26 | (add-to-list 'load-path (expand-file-name "test" hyperb:dir)) 27 | (when (equal (system-name) "norlinux") 28 | ;; Next load line resolves a cyclic dependency issue that breaks 11 tests 29 | ;; on rsw's linux system; please leave it here. 30 | (load "pcomplete")) 31 | 32 | (defun hy-test-ensure-package-installed (pkg-symbol) 33 | (unless (package-installed-p pkg-symbol) 34 | (package-refresh-contents) 35 | (package-install pkg-symbol)) 36 | (require pkg-symbol)) 37 | 38 | (mapc (lambda (sym) (hy-test-ensure-package-installed sym)) 39 | '(el-mock)) 40 | 41 | ;; Needed when `hypb:display-file-with-logo' uses `org-mode' 42 | (setq hsys-org-enable-smart-keys t) 43 | 44 | ;; Log and fix any mixed version Org installation 45 | (hsys-org-log-and-fix-version) 46 | 47 | (provide 'hy-test-dependencies) 48 | ;;; hy-test-dependencies.el ends here 49 | -------------------------------------------------------------------------------- /test/hy-test-helpers.el: -------------------------------------------------------------------------------- 1 | ;;; hy-test-helpers.el --- unit test helpers -*- lexical-binding: t; -*- 2 | 3 | ;; Author: Mats Lidell 4 | ;; 5 | ;; Orig-Date: 30-Jan-21 at 12:00:00 6 | ;; Last-Mod: 1-Jun-25 at 23:22:27 by Mats Lidell 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 2021-2025 Free Software Foundation, Inc. 11 | ;; See the "HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | 15 | ;;; Commentary: 16 | 17 | ;; 18 | 19 | ;;; Code: 20 | 21 | (require 'ert) 22 | (require 'hmouse-drv) ; For `action-key' 23 | (eval-when-compile (require 'cl-lib)) 24 | 25 | (defun hy-test-helpers:consume-input-events () 26 | "Use `recursive-edit' to consume the events kbd-key generates." 27 | (run-with-timer 0.1 nil (lambda () (exit-recursive-edit))) 28 | (recursive-edit)) 29 | 30 | (defun hy-test-helpers:ensure-link-possible-type (type) 31 | "At point, ensure `hui:link-possible-types' returns a single TYPE." 32 | (let* ((possible-types (hui:link-possible-types)) 33 | (first-type (caar possible-types))) 34 | (should (= (length possible-types) 1)) 35 | (should (equal first-type type)))) 36 | 37 | (defun hy-test-helpers:should-last-message (msg captured) 38 | "Verify MSG is in CAPTURED text." 39 | (should (string-search msg captured))) 40 | 41 | (defun hy-test-helpers:action-key-should-call-hpath:find (str) 42 | "Call action-key and check that hpath:find was called with STR." 43 | (let ((was-called nil)) 44 | (cl-letf (((symbol-function 'hpath:find) 45 | (lambda (filename) 46 | (if (not (and (stringp str) (stringp filename))) 47 | (should (eq t (message "str = %s; filename = %s" str filename))) 48 | (setq was-called (should (or (string= str filename) 49 | ;; Support Windows paths 50 | (string= (expand-file-name str) 51 | (expand-file-name filename))))))))) 52 | (action-key) 53 | (should was-called)))) 54 | 55 | (defun hy-test-helpers:hypb-function-should-call-hpath:find (function str) 56 | "Call FUNCTION and check that hpath:find was called with STR." 57 | (let ((was-called nil)) 58 | (cl-letf (((symbol-function 'hpath:find) 59 | (lambda (filename) 60 | (setq was-called (should (or (string= str filename) (string= str (expand-file-name filename)))))))) 61 | (funcall function) 62 | (should was-called)))) 63 | 64 | (defun hy-test-helpers:kill-buffer (buffer) 65 | "Kill BUFFER if it exists." 66 | (when (get-buffer buffer) 67 | (kill-buffer buffer))) 68 | 69 | (cl-defun hy-test-helpers-verify-hattr-at-p (&key actype args loc lbl-key name) 70 | "Verify the attribute of hbut at point. 71 | Checks ACTYPE, ARGS, LOC, LBL-KEY and NAME." 72 | (hbut:at-p) 73 | (should (eq (hattr:get 'hbut:current 'actype) actype)) 74 | (should (equal (hattr:get 'hbut:current 'args) args)) 75 | (should (equal (hattr:get 'hbut:current 'loc) loc)) 76 | (should (equal (hattr:get 'hbut:current 'lbl-key) lbl-key)) 77 | (should (equal (hattr:get 'hbut:current 'name) name))) 78 | 79 | (defun hy-delete-file-and-buffer (file) 80 | "Delete FILE and buffer visiting file." 81 | (let ((buf (find-buffer-visiting file))) 82 | (when buf 83 | (with-current-buffer buf 84 | (set-buffer-modified-p nil) 85 | (kill-buffer)))) 86 | (delete-file file)) 87 | 88 | (defun hy-delete-files-and-buffers (files) 89 | "Delete all FILES and all buffers visiting those files." 90 | (dolist (f files) 91 | (hy-delete-file-and-buffer f))) 92 | 93 | (defun hy-delete-dir-and-buffer (dir) 94 | "Delete DIR and buffer visiting directory." 95 | (let ((buf (find-buffer-visiting dir)) 96 | (hywiki-cache (when (featurep 'hywiki) 97 | (expand-file-name hywiki-cache-default-file 98 | dir)))) 99 | (when buf 100 | (kill-buffer buf)) 101 | (when (and hywiki-cache 102 | (file-readable-p hywiki-cache) 103 | (file-writable-p hywiki-cache)) 104 | (delete-file hywiki-cache)) 105 | (delete-directory dir))) 106 | 107 | (defun hy-make-random-wikiword (&optional length word-length) 108 | "Create a random WikiWord (string). 109 | The WikiWord will have a total of LENGTH characters. Each word part of 110 | the WikiWord will have WORD-LENGTH characters. The default LENGTH is 12 111 | and the default WORD-LENGTH is 4." 112 | (unless length 113 | (setq length 12)) 114 | (unless word-length 115 | (setq word-length 4)) 116 | (let ((chars (vconcat (number-sequence ?a ?z))) 117 | (result "")) 118 | (dotimes (i length) 119 | (when (zerop (mod i word-length)) 120 | (setq result (concat result " "))) 121 | (setq result (concat result (char-to-string (elt chars (random (length chars))))))) 122 | (replace-regexp-in-string "[[:space:]]" "" (capitalize result)))) 123 | 124 | (defvar hy-test-run-failing-flag nil 125 | "Non-nil means test cases that are known to fail will be tried.") 126 | 127 | (defun hy-test-word-face-at-region (beg end) 128 | "Non-nil if all chars in region [BEG, END] have `hywiki--word-face'." 129 | (interactive "r") 130 | (let (no-face) 131 | (while (and (< beg end) (not no-face)) 132 | (unless (hywiki-word-face-at-p beg) 133 | (setq no-face t)) 134 | (setq beg (1+ beg))) 135 | (not no-face))) 136 | 137 | (provide 'hy-test-helpers) 138 | ;;; hy-test-helpers.el ends here 139 | -------------------------------------------------------------------------------- /test/hycontrol-tests.el: -------------------------------------------------------------------------------- 1 | ;;; hycontrol-tests.el --- verify hycontrol -*- lexical-binding: t; -*- 2 | ;; 3 | ;; Author: Mats Lidell 4 | ;; 5 | ;; Orig-Date: 8-Jan-25 at 22:52:00 6 | ;; Last-Mod: 4-Mar-25 at 17:06:26 by Mats Lidell 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 2025 Free Software Foundation, Inc. 11 | ;; See the "HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | 15 | ;;; Commentary: 16 | ;; 17 | ;; Verify functions and features provided by "hycontrol.el". 18 | 19 | ;;; Code: 20 | 21 | (require 'hycontrol) 22 | (require 'ert) 23 | (require 'el-mock) 24 | 25 | (ert-deftest hycontrol-tests--framemove-direction-error-message () 26 | "Verify `hycontrol-framemove-direction' shows message when `framemove' is not available." 27 | (mocklet (((featurep 'framemove) => nil) 28 | ((hycontrol-quit) => t)) 29 | (let ((err (should-error (hycontrol-framemove-direction 'up) :type 'error))) 30 | (should (string-match "Requires manual installation" (cadr err)))))) 31 | 32 | (provide 'hycontrol-tests) 33 | 34 | ;; This file can't be byte-compiled without the `el-mock' package 35 | ;; which is not a dependency of Hyperbole. 36 | ;; 37 | ;; Local Variables: 38 | ;; no-byte-compile: t 39 | ;; End: 40 | 41 | ;;; hycontrol-tests.el ends here 42 | -------------------------------------------------------------------------------- /test/hypb-ert-tests.el: -------------------------------------------------------------------------------- 1 | ;;; hypb-ert-tests.el --- tests for hypb-ert -*- lexical-binding: t; -*- 2 | ;; 3 | ;; Author: Mats Lidell 4 | ;; 5 | ;; Orig-Date: 1-Jan-24 at 23:11:54 6 | ;; Last-Mod: 21-Mar-24 at 10:52:53 by Bob Weiner 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 2024 Free Software Foundation, Inc. 11 | ;; See the "HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | 15 | ;;; Commentary: 16 | ;; 17 | 18 | ;;; Code: 19 | 20 | (require 'ert) 21 | (require 'hy-test-dependencies) ;; can install el-mock 22 | (require 'hypb-ert) 23 | 24 | (ert-deftest hypb-ert-tests--def-at-p () 25 | "Verify an `ert-deftest' name is identified." 26 | (let ((test-name "hypb-ert-tests--test")) 27 | (with-temp-buffer 28 | (insert "(ert-deftest " test-name " ()\n\"Docstring.\"\nt\n)\n") 29 | 30 | (goto-char (point-min)) 31 | (should-not (hypb-ert-def-at-p)) 32 | 33 | (goto-char (1+ (point-min))) 34 | (should (string= (hypb-ert-def-at-p) test-name)) 35 | 36 | (goto-char (- (line-end-position) 3)) 37 | (should (string= (hypb-ert-def-at-p) test-name)) 38 | 39 | (goto-char (- (line-end-position) 2)) 40 | (should-not (hypb-ert-def-at-p)) 41 | 42 | (end-of-line) 43 | (should-not (hypb-ert-def-at-p)) 44 | 45 | (goto-char (1+ (point-min))) 46 | (pcase-let ((`(,name ,start ,end) 47 | (hypb-ert-def-at-p t))) 48 | (should (string= name test-name)) 49 | (should (string= (buffer-substring start end) test-name)))))) 50 | 51 | (ert-deftest hypb-ert-tests--edebug-is-called () 52 | "Verify `edebug-defun' is called when debug-it argument is set." 53 | (let ((test-name "hypb-ert-tests--test")) 54 | (with-temp-buffer 55 | (insert "(ert-deftest " test-name " ()\n\"Docstring.\"\nt\n)\n") 56 | (emacs-lisp-mode) 57 | (goto-char (1+ (point-min))) 58 | (mocklet (((hypb-ert *) => t)) 59 | (hypb-ert-run-test-at-definition t))))) 60 | 61 | (provide 'hypb-ert-tests) 62 | 63 | ;; This file can't be byte-compiled without the `el-mock' package 64 | ;; which is not a dependency of Hyperbole. 65 | ;; 66 | ;; Local Variables: 67 | ;; no-byte-compile: t 68 | ;; End: 69 | 70 | ;;; hypb-ert-tests.el ends here 71 | -------------------------------------------------------------------------------- /test/hypb-tests.el: -------------------------------------------------------------------------------- 1 | ;;; hypb-tests.el --- tests for hypb.el utility functions -*- lexical-binding: t; -*- 2 | 3 | ;; Author: Mats Lidell 4 | ;; 5 | ;; Orig-Date: 5-Apr-21 at 18:53:10 6 | ;; Last-Mod: 27-May-25 at 22:01:13 by Bob Weiner 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 2021-2022 Free Software Foundation, Inc. 11 | ;; See the "HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | 15 | ;;; Commentary: 16 | 17 | ;; Tests for "../hypb.el" 18 | 19 | ;;; Code: 20 | 21 | (require 'hypb) 22 | (require 'hbut) 23 | (require 'ert) 24 | (require 'el-mock) 25 | (require 'hy-test-helpers) 26 | 27 | (ert-deftest hypb:installation-type-test () 28 | "Verify installation type alternatives." 29 | ;; straight.el package install -- hyperbole gnu-elpa-mirror master 56cd3d8 2022-02-05 30 | (require 'package) 31 | (unless package--initialized 32 | (package-initialize)) 33 | (when (featurep 'straight) 34 | (let* ((hyperb:dir (expand-file-name "straight/build/hyperbole" user-emacs-directory)) 35 | (default-directory (expand-file-name "straight/repos/hyperbole" user-emacs-directory)) 36 | (package-installed-p 'straight) 37 | (plist (hypb:straight-package-plist "hyperbole")) 38 | (install-type-list (when plist (hypb:installation-type))) 39 | (commit (nth 1 install-type-list))) 40 | (when plist 41 | (should (and (equal (nth 0 install-type-list) "straight") 42 | commit 43 | (string-match-p "\\`[a-f0-9]+\\'" commit) 44 | t))))) 45 | ;; elpa-devel package install -- hyperbole-8.0.0pre0.20220126.1138 46 | (let ((hyperb:dir (expand-file-name "home/user/.emacs.d/elpa/hyperbole-8.0.0pre0.20220126.1138" "/"))) 47 | (should (equal (hypb:installation-type) '("elpa-devel" "8.0.0pre0.20220126.1138")))) 48 | ;; melpa/quelpa package instball -- hyperbole-20220205.1429 49 | (let ((hyperb:dir (expand-file-name "home/user/.emacs.d/elpa/hyperbole-20220126.1138" "/"))) 50 | (should (equal (hypb:installation-type) '("melpa" "20220126.1138")))) 51 | ;; git install -- hyperbole d43d05a097 52 | (let ((hyperb:dir (expand-file-name "a_git_folder" "/"))) 53 | (with-mock 54 | (mock (file-exists-p (expand-file-name ".git" hyperb:dir)) => t) 55 | (mock (shell-command-to-string "git rev-parse HEAD") => "d43d05a0973e8adcbfdd8c85681dac5de669aaa9") 56 | (should (equal (hypb:installation-type) '("git" "d43d05a097"))))) 57 | ;; elpa package install -- /elpa/hyperbole-8.0.0" 58 | (let ((hyperb:dir (expand-file-name "home/user/.emacs.d/elpa/hyperbole-8.0.0" "/"))) 59 | (should (equal (hypb:installation-type) '("elpa" "8.0.0")))) 60 | ;; tarball archive install -- hyperbole-8.0.0 61 | (let ((hyperb:dir (expand-file-name "home/user/hyperbole-8.0.0" "/"))) 62 | (should (equal (hypb:installation-type) '("archive" "8.0.0")))) 63 | ;; unknown 64 | (let ((hyperb:dir (expand-file-name "home/user/hyperbole" "/"))) 65 | (with-mock 66 | (mock (file-exists-p (expand-file-name ".git" hyperb:dir)) => nil) 67 | (should (equal (car (hypb:installation-type)) "unknown"))))) 68 | 69 | (ert-deftest hypb--oct-to-int () 70 | "Verify oct to int conversion." 71 | (should (= (hypb:oct-to-int 0) 0)) 72 | (should (= (hypb:oct-to-int 1) 1)) 73 | (should (= (hypb:oct-to-int 7) 7)) 74 | (should (= (hypb:oct-to-int 10) 8)) 75 | (should (= (hypb:oct-to-int 2000) 1024)) 76 | (should-error (hypb:oct-to-int 8) :type 'error)) 77 | 78 | (ert-deftest hypb--verify-info-index-is-correct () 79 | "Verify that Hyperbole info page indexes are identified. 80 | See Emacs bug#74042 related to usage of texi2any." 81 | (unwind-protect 82 | (progn 83 | (Info-goto-node "(Hyperbole)Top") 84 | (should (set:equal '("Key Index" "Function Index" "Concept Index") (Info-index-nodes)))) 85 | (hy-test-helpers:kill-buffer "*info*"))) 86 | 87 | (ert-deftest hypb--in-string-p () 88 | "Verify basic quote handing by `hypb:in-string-p'." 89 | (let ((s '(("\"str\"" . text-mode) ;; double-quotes: 90 | ("'str'" . python-mode) ;; Python single-quotes: 91 | ("'''str'''" . python-mode) ;; Python triple single-quotes: 92 | ("\"\"\"str\"\"\"" . python-mode) ;; Python triple double-quotes: 93 | ("``str''" . texinfo-mode)))) ;; Texinfo open and close quotes: 94 | (dolist (v s) 95 | (let ((str (car v)) 96 | (mode (cdr v))) 97 | (with-temp-buffer 98 | (funcall mode) 99 | (insert str) 100 | (goto-char (/ (length str) 2)) 101 | (should (hypb:in-string-p)) 102 | (let ((seq (hypb:in-string-p nil t))) 103 | (should (sequencep seq)) 104 | (cl-destructuring-bind (val beg end) seq 105 | (should val) 106 | (should (and beg end (= (- end beg) 3)))))))))) 107 | 108 | (ert-deftest hypb--in-string-p--max-lines () 109 | "Verify max lines handing by `hypb:in-string-p'." 110 | (with-temp-buffer 111 | (insert "\ 112 | \"1 113 | 2 114 | \"") 115 | (goto-line 1) (move-to-column 1) 116 | ;; First line. Line starts with quote. 117 | (should-not (hypb:in-string-p 1)) 118 | (should-not (hypb:in-string-p 2)) 119 | (should (hypb:in-string-p 3)) 120 | (should (hypb:in-string-p 99)) 121 | 122 | ;; Second line. No quote on the line. 123 | (goto-line 2) 124 | (dotimes (l 5) 125 | (should-not (hypb:in-string-p l))))) 126 | 127 | ;; This file can't be byte-compiled without the `el-mock' package (because of 128 | ;; the use of the `with-mock' macro), which is not a dependency of Hyperbole. 129 | ;; Local Variables: 130 | ;; no-byte-compile: t 131 | ;; End: 132 | 133 | (provide 'hypb-tests) 134 | ;;; hypb-tests.el ends here 135 | -------------------------------------------------------------------------------- /test/hyperbole-tests.el: -------------------------------------------------------------------------------- 1 | ;;; hyperbole-tests.el --- tests for hyperbole.el -*- lexical-binding: t; -*- 2 | ;; 3 | ;; Author: Mats Lidell 4 | ;; 5 | ;; Orig-Date: 8-Jan-22 at 23:40:00 6 | ;; Last-Mod: 28-Aug-23 at 00:15:21 by Bob Weiner 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 2022 Free Software Foundation, Inc. 11 | ;; See the "HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | 15 | ;;; Commentary: 16 | ;; 17 | ;; Tests for "../hyperbole.el" 18 | 19 | ;;; Code: 20 | 21 | (require 'ert) 22 | (require 'hyperbole) 23 | 24 | ;; The reason verify-keybinding in these tests is a macro instead of a 25 | ;; function is that in the event of a failure, it makes the keybinding 26 | ;; that failed show up in ERT's output. -- Copied from edebug-tests.el 27 | 28 | (defun hyperbole-key-bindings (set) 29 | "If SET is t, verify keys are bound and if nil, verify they are unbound." 30 | (let ((hyperbole-mode-map (make-sparse-keymap)) 31 | (hkey-init set)) 32 | (cl-letf (((symbol-function 'where-is-internal) (lambda (_func &optional _map) nil)) 33 | ((symbol-function 'hyperb:window-system) (lambda () t))) 34 | (hkey-initialize) 35 | (cl-macrolet ((verify-keybinding (verify key binding) 36 | `(if ,verify 37 | (should (eq (lookup-key hyperbole-mode-map ,key) 38 | ,binding)) 39 | (should-not (eq (lookup-key hyperbole-mode-map ,key) 40 | ,binding))))) 41 | (verify-keybinding set "\C-c@" #'hycontrol-windows-grid) 42 | (verify-keybinding set "\C-c\C-m" #'hui-select-thing) 43 | (verify-keybinding set "\C-c\\" #'hycontrol-enable-windows-mode) 44 | (verify-keybinding set "\C-c/" #'hui-search-web) 45 | (verify-keybinding set "\C-c." #'hui-select-goto-matching-delimiter) 46 | (mapc (lambda (key) (verify-keybinding set (kbd key) #'hkey-either)) 47 | '("\M-\C-m" "M-RET" "ESC RET" "ESC " "M-")) 48 | (verify-keybinding set "\C-hA" #'hkey-help) 49 | (verify-keybinding set "\M-o" #'hkey-operate))))) 50 | 51 | (ert-deftest hyperbole-keymap-tests () 52 | "Verify all key bindings are set." 53 | (hyperbole-key-bindings t)) 54 | 55 | (ert-deftest hyperbole-hkey-init-controls-tests () 56 | "Verify all key bindings are set." 57 | (hyperbole-key-bindings nil)) 58 | 59 | (ert-deftest hyperbole-global-key-binding-tests () 60 | "Verify the global keys are bound." 61 | (let ((hyperbole-mode-map (make-sparse-keymap)) 62 | (hkey-init t)) 63 | (hkey-initialize) 64 | (cl-macrolet ((verify-keybinding (key binding) 65 | `(should (eq (lookup-key global-map ,key) ,binding)))) 66 | (verify-keybinding "\C-hh" #'hyperbole)))) 67 | 68 | (provide 'hyperbole-tests) 69 | ;;; hyperbole-tests.el ends here 70 | -------------------------------------------------------------------------------- /test/hywconfig-tests.el: -------------------------------------------------------------------------------- 1 | ;;; hywconfig-tests.el --- unit tests for hywconfig -*- lexical-binding: t; -*- 2 | 3 | ;; Author: Mats Lidell 4 | ;; 5 | ;; Orig-Date: 30-Jan-21 at 12:00:00 6 | ;; Last-Mod: 23-Dec-23 at 01:21:53 by Bob Weiner 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 2023 Free Software Foundation, Inc. 11 | ;; See the "HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | 15 | ;;; Commentary: 16 | 17 | ;; Unit tests for "../hywconfig.el" 18 | 19 | ;;; Code: 20 | 21 | (require 'hywconfig) 22 | (require 'ert) 23 | 24 | (defun hywconfig-tests--remove-ring () 25 | "Remove ring from frame parameters." 26 | (set-frame-parameter nil 'hywconfig-ring nil)) 27 | 28 | (defun hywconfig-tests--remove-names () 29 | "Remove names from frame parameters." 30 | (set-frame-parameter nil 'named-hywconfigs nil)) 31 | 32 | (ert-deftest hywconfig--inital-ring-is-empty () 33 | "Verify an initial ring is empty." 34 | (hywconfig-tests--remove-ring) 35 | (should (hywconfig-ring-empty-p))) 36 | 37 | (ert-deftest hywconfig--not-empty-if-ring-save () 38 | "Verify ring is not empty after saving a configuration." 39 | (hywconfig-tests--remove-ring) 40 | (hywconfig-ring-save) 41 | (should-not (hywconfig-ring-empty-p))) 42 | 43 | (ert-deftest hywconfig--number-of-configs-are-store-up-to-a-max () 44 | "Verify there is a max of number of configuration that can be saved." 45 | (let ((hywconfig-ring-max 2)) 46 | (hywconfig-tests--remove-ring) 47 | (hywconfig-ring-save) 48 | (hywconfig-ring-save) 49 | (should (= (ring-length (hywconfig-get-ring)) hywconfig-ring-max)) 50 | (hywconfig-ring-save) 51 | (should (= (ring-length (hywconfig-get-ring)) hywconfig-ring-max)))) 52 | 53 | (ert-deftest hywconfig--empty-after-pop-ring-with-one-config () 54 | "Verify ring is not empty after saving a configuration." 55 | (hywconfig-tests--remove-ring) 56 | (hywconfig-ring-save) 57 | (hywconfig-delete-pop) 58 | (should (hywconfig-ring-empty-p))) 59 | 60 | (ert-deftest hywconfig--max-minus-one-after-pop-ring-with-max-config () 61 | "Verify ring is not empty after saving a configuration." 62 | (let ((hywconfig-ring-max 2)) 63 | (hywconfig-tests--remove-ring) 64 | (hywconfig-ring-save) 65 | (hywconfig-ring-save) 66 | (hywconfig-delete-pop) 67 | (should (= (ring-length (hywconfig-get-ring)) (1- hywconfig-ring-max))))) 68 | 69 | (ert-deftest hywconfig--get-not-existing-config-errors () 70 | "Verify retrieving a config that has not been saved gives an error message." 71 | (hywconfig-tests--remove-names) 72 | (let ((err (should-error (hywconfig-restore-by-name "config") :type 'error))) 73 | (should (string-match-p "No window configuration for this frame named" (cadr err))))) 74 | 75 | (ert-deftest hywconfig--add-by-name () 76 | "Verify config is added by name." 77 | (hywconfig-tests--remove-names) 78 | (hywconfig-add-by-name "config") 79 | (should (hywconfig-named-get "config")) 80 | (should (hywconfig-restore-by-name "config"))) 81 | 82 | (ert-deftest hywconfig--delete-by-name () 83 | "Verify config can be deleted by name." 84 | ;; Same error as above 85 | (hywconfig-tests--remove-names) 86 | (should (hywconfig-add-by-name "config")) 87 | (should (hywconfig-delete-by-name "config")) 88 | (let ((err (should-error (hywconfig-restore-by-name "config") :type 'error))) 89 | (should (string-match-p "No window configuration for this frame named" (cadr err))))) 90 | 91 | (provide 'hywconfig-tests) 92 | ;;; hywconfig-tests.el ends here 93 | -------------------------------------------------------------------------------- /test/kcell-tests.el: -------------------------------------------------------------------------------- 1 | ;;; kcell-tests.el --- Test for kcells in Koutliner -*- lexical-binding: t; -*- 2 | ;; usage: GNU Emacs Lisp Library 3 | ;; keywords: test 4 | ;; 5 | ;; author: Mats Lidell 6 | ;; org: Free Software Foundation, Inc. 7 | ;; e-mail: matsl@gnu.org 8 | ;; 9 | ;; orig-date: 16-Feb-22 at 23:28:49 10 | ;; last-mod: 16-Mar-25 at 10:15:23 by Bob Weiner 11 | ;; 12 | ;; SPDX-License-Identifier: GPL-3.0-or-later 13 | ;; 14 | ;; Copyright (C) 2021-2024 Free Software Foundation, Inc. 15 | ;; Licensed under the GNU General Public License, version 3. 16 | ;; 17 | ;; This file is not part of Emacs. It requires Emacs 28 or above. 18 | ;; This file is part of Hyperbole. 19 | ;; 20 | ;;; Commentary: 21 | ;; 22 | ;; Tests for "../kotl/kcell.el" 23 | ;; 24 | 25 | ;;; Code: 26 | 27 | (require 'kcell "kotl/kcell") 28 | (require 'kotl-mode) 29 | (require 'hy-test-helpers "test/hy-test-helpers") 30 | 31 | (defconst kcell-tests--ref-to-id-tests 32 | ; ref flag kvspec expected 33 | '((0 nil "ben" 0) 34 | (0 t "ben" 0) 35 | (1 nil "ben" 1) 36 | (1 t "ben" 1) 37 | 38 | ("1" nil "ben" 1) 39 | ("1" t "ben" 1) 40 | ("1a" nil "ben" 3) 41 | ("1a" t "ben" 3) 42 | ("1.1" nil "ben." 3) 43 | ("1.1" t "ben." 3) 44 | (01 nil "ben" 1) 45 | (01 t "ben" 1) 46 | 47 | ("1a=03" nil "ben" 3) 48 | ("1a=03" t "ben" 3) 49 | ("1.1=03" nil "ben." 3) 50 | ("1.1=03" t "ben." 3) 51 | 52 | ("1|xyz" nil "ben" 1) 53 | ("1|xyz" t "ben" "01|xyz") 54 | ("1a|xyz" nil "ben" 3) 55 | ("1a|xyz" t "ben" "03|xyz") 56 | ("1.1|xyz" nil "ben." 3) 57 | ("1.1|xyz" t "ben." "03|xyz") 58 | 59 | ("1a=03|xyz" nil "ben" 3) 60 | ("1a=03|xyz" t "ben" "03|xyz") 61 | ("1.1=03|xyz" nil "ben." 3) 62 | ("1.1=03|xyz" t "ben." "03|xyz") 63 | 64 | ("1=03|xyz" t "ben" "03|xyz") 65 | ("1.2=03|xyz" t "ben." "03|xyz") 66 | 67 | ("1a" nil "ben0" nil) 68 | ("1.1" nil "ben0" nil)) 69 | "Test cases on the form list of REF FLAG KVSPEC EXPECTED.") 70 | 71 | (defun kcell-tests--check-ref-to-id (spec) 72 | "Check if ref-to-id return expected value given in SPEC. 73 | Return t if is does else return the SPEC." 74 | (let ((ref (nth 0 spec)) 75 | (flag (nth 1 spec)) 76 | (kvspec (nth 2 spec)) 77 | (expected (nth 3 spec))) 78 | (kvspec:activate kvspec) 79 | (or (equal (kcell:ref-to-id ref flag) expected) spec))) 80 | 81 | (ert-deftest kcell-tests--ref-to-id () 82 | "Verify all ref to id transformations." 83 | (let ((kotl-file (make-temp-file "hypb" nil ".kotl"))) 84 | (unwind-protect 85 | (progn 86 | (find-file kotl-file) 87 | (kotl-mode:add-child) 88 | (let ((failures (delq t (mapcar (lambda (x) (funcall #'kcell-tests--check-ref-to-id x)) kcell-tests--ref-to-id-tests)))) 89 | (if failures 90 | (ert-fail (cons "These refs were not correctly converted to ids:" failures)) 91 | t))) 92 | (hy-delete-file-and-buffer kotl-file)))) 93 | 94 | (provide 'kcell-tests) 95 | ;;; kcell-tests.el ends here 96 | -------------------------------------------------------------------------------- /test/kimport-tests.el: -------------------------------------------------------------------------------- 1 | ;;; kimport-tests.el --- test importing file types to Koutlines -*- lexical-binding: t; -*- 2 | ;; 3 | ;; Author: Mats Lidell 4 | ;; 5 | ;; Orig-Date: 9-Apr-23 at 23:31:48 6 | ;; Last-Mod: 22-Feb-24 at 00:02:33 by Mats Lidell 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 2021-2022 Free Software Foundation, Inc. 11 | ;; See the "HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | 15 | ;;; Commentary: 16 | ;; 17 | 18 | ;;; Code: 19 | 20 | (require 'kimport) 21 | (require 'ert) 22 | (require 'hy-test-helpers "test/hy-test-helpers") 23 | 24 | (ert-deftest kimport--aug-post-outline () 25 | "Import .otl star outline as one cell per entry beginning with one or more stars." 26 | (let ((file (make-temp-file "hypb" nil ".aug" 27 | (concat "entry1 1\n\nentry1a 1a\n\nentry1b 1b\n\n" 28 | "entry2 2\n\nentry3 3\n\nentry3a 3a\n"))) 29 | (kotl-file (make-temp-file "hypb" nil ".kotl"))) 30 | (unwind-protect 31 | (progn 32 | (find-file file) 33 | (kimport:file file kotl-file) 34 | (find-file kotl-file) 35 | (dolist (v '("entry1" "entry1a" "entry1b" "entry2" "entry3" "entry3a")) 36 | (should (looking-at-p v)) 37 | (should (string-suffix-p (kcell-view:label) v)) 38 | (unless (kotl-mode:last-cell-p) 39 | (kotl-mode:next-cell 1))) 40 | (should (kotl-mode:last-cell-p))) 41 | (hy-delete-file-and-buffer file) 42 | (hy-delete-file-and-buffer kotl-file)))) 43 | 44 | (ert-deftest kimport--text-file () 45 | "Import .txt text file into a Koutline, as one cell per paragraph." 46 | (let ((file (make-temp-file "hypb" nil ".txt" "1\n\n2\n\n3\n")) 47 | (kotl-file (make-temp-file "hypb" nil ".kotl"))) 48 | (unwind-protect 49 | (progn 50 | (find-file file) 51 | (kimport:file file kotl-file) 52 | (find-file kotl-file) 53 | (dolist (v '(1 2 3)) 54 | (should (looking-at-p (number-to-string v))) 55 | (unless (kotl-mode:last-cell-p) 56 | (kotl-mode:forward-cell 1))) 57 | (should (kotl-mode:last-cell-p))) 58 | (hy-delete-file-and-buffer file) 59 | (hy-delete-file-and-buffer kotl-file)))) 60 | 61 | (ert-deftest kimport--text-file-two-lines-per-paragraph () 62 | "Import .txt text file into a Koutline, as one cell per paragraph. 63 | Each paragraph is two lines." 64 | (let ((file (make-temp-file "hypb" nil ".txt" 65 | (concat "par1 line1\npar1 line2\n\n\npar2 line3\n par2 line4" 66 | "\n\n par3 *. line5\n par3 *. line6"))) 67 | (kotl-file (make-temp-file "hypb" nil ".kotl"))) 68 | (unwind-protect 69 | (progn 70 | (find-file file) 71 | (kimport:file file kotl-file) 72 | (find-file kotl-file) 73 | (dolist (v '("par1 line1\\s-+par1 line2" "par2 line3\\s-+par2 line4" 74 | "par3 \\*\\. line5\\s-+par3 \\*\\. line6")) 75 | (should (looking-at-p v)) 76 | (unless (kotl-mode:last-cell-p) 77 | (kotl-mode:forward-cell 1))) 78 | (should (kotl-mode:last-cell-p))) 79 | (hy-delete-file-and-buffer file) 80 | (hy-delete-file-and-buffer kotl-file)))) 81 | 82 | (ert-deftest kimport--star-outline () 83 | "Import .otl star outline as one cell per entry beginning with one or more stars." 84 | (let ((file (make-temp-file "hypb" nil ".otl" "* 1\n** 1a\n** 1b\n* 2\n* 3\n** 3a\n")) 85 | (kotl-file (make-temp-file "hypb" nil ".kotl"))) 86 | (unwind-protect 87 | (progn 88 | (find-file file) 89 | (kimport:file file kotl-file) 90 | (find-file kotl-file) 91 | (dolist (v '("1" "1a" "1b" "2" "3" "3a")) 92 | (should (looking-at-p v)) 93 | (should (equal (kcell-view:label) v)) 94 | (unless (kotl-mode:last-cell-p) 95 | (kotl-mode:next-cell 1))) 96 | (should (kotl-mode:last-cell-p))) 97 | (hy-delete-file-and-buffer file) 98 | (hy-delete-file-and-buffer kotl-file)))) 99 | 100 | (ert-deftest kimport--star-outline-two-lines-per-star-heading () 101 | "Import .org star outline as one cell per paragraph, each two lines." 102 | (let ((file (make-temp-file "hypb" nil ".org" "* 1\n2\n* 3\n4\n* 5\n6\n")) 103 | (kotl-file (make-temp-file "hypb" nil ".kotl"))) 104 | (unwind-protect 105 | (progn 106 | (find-file file) 107 | (kimport:file file kotl-file) 108 | (find-file kotl-file) 109 | (dolist (v '("1\n.*2" "3\n.*4" "5\n.*6")) 110 | (should (looking-at-p v)) 111 | (unless (kotl-mode:last-cell-p) 112 | (kotl-mode:forward-cell 1))) 113 | (should (kotl-mode:last-cell-p))) 114 | (hy-delete-file-and-buffer file) 115 | (hy-delete-file-and-buffer kotl-file)))) 116 | 117 | (ert-deftest kimport--star-outline-with-siblings () 118 | "Import .org star outline as one cell per entry beginning with one or more stars." 119 | (let ((file (make-temp-file "hypb" nil ".org" "* 1\n** 2\n*** 3\n")) 120 | (kotl-file (make-temp-file "hypb" nil ".kotl"))) 121 | (unwind-protect 122 | (progn 123 | (find-file file) 124 | (kimport:file file kotl-file) 125 | (find-file kotl-file) 126 | (dolist (v '(1 2)) 127 | (should (looking-at-p (number-to-string v))) 128 | (unless (kotl-mode:last-cell-p) 129 | (kotl-mode:next-cell 1))) 130 | (should (looking-at-p (number-to-string 3))) 131 | (should (kotl-mode:last-cell-p)) 132 | (kotl-mode:end-of-buffer) 133 | (should (= (kcell-view:level) 3))) 134 | (hy-delete-file-and-buffer file) 135 | (hy-delete-file-and-buffer kotl-file)))) 136 | 137 | (provide 'kimport-tests) 138 | ;;; kimport-tests.el ends here 139 | -------------------------------------------------------------------------------- /test/kotl-orgtbl-tests.el: -------------------------------------------------------------------------------- 1 | ;;; kotl-orgtbl-tests.el --- kotl orgtbl tests -*- lexical-binding: t; -*- 2 | 3 | ;; Author: Mats Lidell 4 | ;; 5 | ;; Orig-Date: 2-Nov-21 at 17:04:30 6 | ;; Last-Mod: 27-Dec-23 at 16:54:00 by Mats Lidell 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 2021-2022 Free Software Foundation, Inc. 11 | ;; See the "HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | 15 | ;;; Commentary: 16 | 17 | ;; Tests for kotl-orgtbl in "../kotl/kotl-orgtbl.el" 18 | 19 | ;;; Code: 20 | 21 | (require 'ert) 22 | (require 'kotl-mode "kotl/kotl-mode") 23 | (require 'hy-test-helpers "test/hy-test-helpers") 24 | 25 | (declare-function hy-test-helpers:consume-input-events "hy-test-helpers") 26 | 27 | (ert-deftest kotl-orgtbl-enabled-uses-kotl-mode-delete-char-outside-of-table () 28 | "kotl-mode:delete-char is used outside of org table." 29 | (let ((kotl-file (make-temp-file "hypb" nil ".kotl"))) 30 | (unwind-protect 31 | (progn 32 | (find-file kotl-file) 33 | (insert "1") 34 | 35 | ;; Create an org table and leave point at end of cell 36 | (should (hact 'kbd-key "RET |field1|field2| RET")) 37 | (hy-test-helpers:consume-input-events) 38 | 39 | ;; Verify that kotl-mode:delete-char is used outside of the 40 | ;; table 41 | (condition-case err 42 | (progn 43 | (should (hact 'kbd-key "C-d")) 44 | (hy-test-helpers:consume-input-events)) 45 | (error 46 | (progn 47 | (should (equal (car err) 'error)) 48 | (should (string-match "(kotl-mode:delete-char): End of cell" (cadr err))))) 49 | (:success (ert-fail "C-d shall fail when deleting at the end of a cell.")))) 50 | (hy-delete-file-and-buffer kotl-file)))) 51 | 52 | (ert-deftest kotl-orgtbl-action-key-on-vertical-bar-toggles-orgtbl-mode () 53 | "Action key on vertical bar toggles orgtbl-mode." 54 | (let ((kotl-file (make-temp-file "hypb" nil ".kotl"))) 55 | (unwind-protect 56 | (progn 57 | (find-file kotl-file) 58 | (should orgtbl-mode) 59 | 60 | ;; Create an org table 61 | (should (hact 'kbd-key "RET |field1|field2| RET")) 62 | (hy-test-helpers:consume-input-events) 63 | 64 | (kotl-mode:backward-char 1) 65 | (action-key) 66 | (should-not orgtbl-mode) 67 | (action-key) 68 | (should orgtbl-mode)) 69 | (hy-delete-file-and-buffer kotl-file)))) 70 | 71 | (ert-deftest kotl-orgtbl-shift-tab-demotes-tree-outside-table () 72 | "Shift tab demotes tree outside of org table." 73 | (let ((kotl-file (make-temp-file "hypb" nil ".kotl"))) 74 | (unwind-protect 75 | (progn 76 | (find-file kotl-file) 77 | (should orgtbl-mode) 78 | 79 | (kotl-mode:add-child) 80 | (should (string= (kcell-view:label (point)) "1a")) 81 | 82 | (should (hact 'kbd-key "")) 83 | (hy-test-helpers:consume-input-events) 84 | 85 | (should (equal (kcell-view:level) 1)) 86 | (should (string= (kcell-view:label (point)) "2"))) 87 | (hy-delete-file-and-buffer kotl-file)))) 88 | 89 | (provide 'kotl-orgtbl-tests) 90 | ;;; kotl-orgtbl-tests.el ends here 91 | -------------------------------------------------------------------------------- /test/smart-org-tests.el: -------------------------------------------------------------------------------- 1 | ;;; smart-org-tests.el --- smart-org-el tests -*- lexical-binding: t; -*- 2 | 3 | ;; Author: Mats Lidell 4 | ;; 5 | ;; Orig-Date: 23-Apr-21 at 22:21:00 6 | ;; Last-Mod: 19-Aug-24 at 22:00:29 by Bob Weiner 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 2021-2022 Free Software Foundation, Inc. 11 | ;; See the "HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | 15 | ;;; Commentary: 16 | 17 | ;; Tests for smart-org in "../hui-mouse.el" 18 | 19 | ;;; Code: 20 | 21 | (require 'ert) 22 | (require 'hui-mouse) 23 | (require 'hact) 24 | (require 'el-mock) 25 | (require 'hy-test-helpers "test/hy-test-helpers") 26 | 27 | (declare-function hy-test-helpers:hypb-function-should-call-hpath:find "hy-test-helpers") 28 | 29 | (ert-deftest smart-org-mode-on-header-cycles-visibility () 30 | "With smart keys on an outline header `smart-org' cycles visibility." 31 | (with-temp-buffer 32 | (let ((bn (buffer-name)) 33 | (hsys-org-enable-smart-keys t)) 34 | (org-mode) 35 | (insert "* 1\n** 2\n*** 3\n") 36 | (goto-char 1) 37 | (should (not (org-check-for-hidden 'headlines))) 38 | (smart-org) 39 | ;; Setting the buffer should not be needed but for some reason 40 | ;; it looks like we get into ert buffer after smart-org 41 | (set-buffer bn) 42 | (should (org-check-for-hidden 'headlines)) 43 | (next-line) 44 | (should (equal (line-number-at-pos) 4))))) 45 | 46 | ;; Smart Key Context 47 | (ert-deftest smart-org-mode-with-smart-keys-on-delimited-thing-activates () 48 | "With smart keys on delimited thing activates selection." 49 | (with-temp-buffer 50 | (let ((hsys-org-enable-smart-keys t)) 51 | (org-mode) 52 | (insert "(hy per bo le)\n") 53 | (goto-char 14) 54 | (action-key) 55 | (should (equal (point) 1))))) 56 | 57 | ;; Hyperbole Button 58 | (ert-deftest smart-org-mode-with-smart-keys-on-hypb-button-activates () 59 | "With smart keys on hypb button activates the button." 60 | (with-temp-buffer 61 | (let ((hsys-org-enable-smart-keys t)) 62 | (org-mode) 63 | (insert "/tmp") 64 | (goto-char 1) 65 | (hy-test-helpers:hypb-function-should-call-hpath:find 66 | 'ibtypes::pathname 67 | (expand-file-name "tmp" "/"))))) 68 | 69 | ;; Hyperbole Button 70 | (ert-deftest smart-org-mode-with-smart-keys-buttons-on-hypb-button-activates () 71 | "With smart keys as buttons on hypb button activates the button." 72 | (with-temp-buffer 73 | (let ((hsys-org-enable-smart-keys :buttons)) 74 | (org-mode) 75 | (insert "/tmp") 76 | (goto-char 2) 77 | (hy-test-helpers:hypb-function-should-call-hpath:find 78 | 'action-key (expand-file-name "tmp" "/"))))) 79 | 80 | ;; Org Link 81 | (ert-deftest smart-org-mode-with-smart-keys-on-org-link-activates () 82 | "With smart keys on `org-mode' link activates link." 83 | (with-temp-buffer 84 | (let ((hsys-org-enable-smart-keys t)) 85 | (org-mode) 86 | (insert "[[/tmp][desc]]") 87 | (goto-char 9) 88 | (with-mock 89 | (mock (org-open-at-point) => t) 90 | (smart-org))))) 91 | 92 | ;; Smart Key Context 93 | (ert-deftest smart-org-mode-with-smart-keys-buttons-on-delimited-thing-calls-org-meta-return () 94 | "With smart keys as buttons on delimited falls back to `org-meta-return'." 95 | (with-temp-buffer 96 | (let ((hsys-org-enable-smart-keys :buttons)) 97 | (org-mode) 98 | (insert "(hy per bo le)\n") 99 | (goto-char 14) 100 | (with-mock 101 | (mock (hsys-org-meta-return) => t) 102 | (smart-org))))) 103 | 104 | ;; Org Link 105 | (ert-deftest smart-org-mode-with-smart-keys-buttons-on-org-link-activates () 106 | "With smart keys as buttons on `org-mode' link activates link." 107 | (with-temp-buffer 108 | (let ((hsys-org-enable-smart-keys :buttons)) 109 | (org-mode) 110 | (insert "[[/tmp][desc]]") 111 | (goto-char 9) 112 | (with-mock 113 | (mock (org-open-at-point) => t) 114 | (smart-org))))) 115 | 116 | ;; Smart Key Context 117 | (ert-deftest smart-org-mode-with-no-smart-keys-on-delimited-thing-calls-org-meta-return () 118 | "With no smart keys on file calls `org-meta-return'." 119 | (with-temp-buffer 120 | (let ((bn (buffer-name)) 121 | (hsys-org-enable-smart-keys nil)) 122 | (org-mode) 123 | (insert "(hy per bo le)\n") 124 | (goto-char 14) 125 | (smart-org) 126 | (set-buffer bn) 127 | (should (string= (buffer-string) "(hy per bo le\n* )\n"))))) 128 | 129 | ;; Hyperbole Button 130 | (ert-deftest smart-org-mode-with-no-smart-keys-on-hypb-button-calls-org-meta-return () 131 | "With no smart keys on file calls `org-meta-return'." 132 | (with-temp-buffer 133 | (let ((hsys-org-enable-smart-keys nil)) 134 | (org-mode) 135 | (insert "/tmp") 136 | (goto-char 1) 137 | (with-mock 138 | (mock (hsys-org-meta-return) => t) 139 | (smart-org))))) 140 | 141 | ;; Org Link 142 | (ert-deftest smart-org-mode-with-no-smart-keys-on-org-link-is-org-meta-return () 143 | "With no smart keys on `org-mode' link calls `org-meta-return'." 144 | (with-temp-buffer 145 | (let ((hsys-org-enable-smart-keys nil)) 146 | (org-mode) 147 | (insert "[[/tmp][desc]]") 148 | (goto-char 9) 149 | (with-mock 150 | (mock (hsys-org-meta-return) => t) 151 | (smart-org))))) 152 | 153 | ;; Compilation requires `el-mock' which is not `Package-Require'd. 154 | ;; Local Variables: 155 | ;; no-byte-compile: t 156 | ;; End: 157 | 158 | (provide 'smart-org-tests) 159 | ;;; smart-org-tests.el ends here 160 | -------------------------------------------------------------------------------- /test/test-helpers-tests.el: -------------------------------------------------------------------------------- 1 | ;;; test-helpers-tests.el --- tests of the test helpers -*- lexical-binding: t; -*- 2 | ;; 3 | ;; Author: Mats Lidell 4 | ;; 5 | ;; Orig-Date: 20-Jan-25 at 20:22:05 6 | ;; Last-Mod: 21-Jan-25 at 17:02:12 by Mats Lidell 7 | ;; 8 | ;; SPDX-License-Identifier: GPL-3.0-or-later 9 | ;; 10 | ;; Copyright (C) 2025 Free Software Foundation, Inc. 11 | ;; See the "HY-COPY" file for license information. 12 | ;; 13 | ;; This file is part of GNU Hyperbole. 14 | 15 | ;;; Commentary: 16 | ;; 17 | ;; These are tests for the test helpers used in other tests. 18 | 19 | ;;; Code: 20 | 21 | (require 'ert) 22 | (require 'hy-test-helpers) 23 | 24 | (unless (fboundp #'char-uppercase-p) 25 | (defun char-uppercase-p (char) 26 | "Return non-nil if CHAR is an upper-case character. 27 | If the Unicode tables are not yet available, e.g. during bootstrap, 28 | then gives correct answers only for ASCII characters." 29 | (cond ((unicode-property-table-internal 'lowercase) 30 | (characterp (get-char-code-property char 'lowercase))) 31 | ((<= ?A char ?Z))))) 32 | 33 | (ert-deftest test-helpers-test--make-random-wikiword () 34 | "Verify hy-make-random-wikiword." 35 | (should (= 12 (length (hy-make-random-wikiword)))) 36 | (dolist (wwl '(3 9 21)) 37 | (dolist (wl '(2 3 9)) 38 | (let ((ww (hy-make-random-wikiword wwl wl))) 39 | (should (= wwl (length ww))) 40 | (should (char-uppercase-p (string-to-char (substring ww 0 1)))) 41 | (should-not (char-uppercase-p (string-to-char (substring ww 1 2)))))))) 42 | 43 | (provide 'test-helpers-tests) 44 | ;;; test-helpers-tests.el ends here 45 | -------------------------------------------------------------------------------- /topwin.py: -------------------------------------------------------------------------------- 1 | #!python 2 | # 3 | # SUMMARY: Outputs the [application name] of the topmost window at mouse screen position or nothing if none 4 | # USAGE: