├── gantt-short.png ├── emacs-learning-curve.jpg ├── LICENSE.txt ├── init.el ├── README.md └── emacs.el /gantt-short.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MooersLab/configorg/main/gantt-short.png -------------------------------------------------------------------------------- /emacs-learning-curve.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MooersLab/configorg/main/emacs-learning-curve.jpg -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Blaine Mooers and the University of Oklahoma Board of Regents 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /init.el: -------------------------------------------------------------------------------- 1 | ; ;; Added by Package.el. This must come before configurations of 2 | (package-initialize) 3 | (add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/")) 4 | (setq inhibit-splash-screen t) 5 | (global-display-line-numbers-mode) 6 | 7 | ;; Make sure that use-package is installed: 8 | (unless (package-installed-p 'use-package) 9 | (package-refresh-contents) 10 | (package-install 'use-package)) 11 | ;; Load use-package: 12 | (eval-when-compile 13 | (require 'use-package)) 14 | 15 | (setq my-user-emacs-directory "~/.emacs.default/") 16 | 17 | 18 | (require 'org-loaddefs) 19 | 20 | (require 'org) 21 | 22 | 23 | ;; ======================================================================================= 24 | ;; The init.el file looks for "config.org" and tangles its elisp blocks (matching 25 | ;; the criteria described below) to "config.el" which is loaded as Emacs configuration. 26 | ;; Inspired and copied from: http://www.holgerschurig.de/en/emacs-init-tangle/ 27 | ;; This code is from Karl Voit: https://raw.githubusercontent.com/novoid/dot-emacs/master/init.el 28 | ;; ======================================================================================= 29 | 30 | 31 | ;; from: http://stackoverflow.com/questions/251908/how-can-i-insert-current-date-and-time-into-a-file-using-emacs 32 | (defvar current-date-time-format "%a %b %d %Y-%m-%dT%H:%M:%S " 33 | "Format of date to insert with `insert-current-date-time' func 34 | See help of `format-time-string' for possible replacements") 35 | 36 | ;; from: http://stackoverflow.com/questions/251908/how-can-i-insert-current-date-and-time-into-a-file-using-emacs 37 | (defvar current-time-format "%a %H:%M:%S" 38 | "Format of date to insert with `insert-current-time' func. 39 | Note the weekly scope of the command's precision.") 40 | 41 | 42 | (defun my-tangle-config-org () 43 | "This function will write all source blocks from =config.org= into =config.el= that are ... 44 | 45 | - not marked as =tangle: no= 46 | - doesn't have the TODO state =DISABLED= 47 | - have a source-code of =emacs-lisp=" 48 | (require 'org) 49 | (let* ((body-list ()) 50 | (output-file (concat my-user-emacs-directory "config.el")) 51 | (org-babel-default-header-args (org-babel-merge-params org-babel-default-header-args 52 | (list (cons :tangle output-file))))) 53 | (message "—————• Re-generating %s …" output-file) 54 | (save-restriction 55 | (save-excursion 56 | (org-babel-map-src-blocks (concat my-user-emacs-directory "config.org") 57 | (let* ( 58 | (org_block_info (org-babel-get-src-block-info 'light)) 59 | ;;(block_name (nth 4 org_block_info)) 60 | (tfile (cdr (assq :tangle (nth 2 org_block_info)))) 61 | (match_for_TODO_keyword) 62 | ) 63 | (save-excursion 64 | (catch 'exit 65 | ;;(when (string= "" block_name) 66 | ;; (message "Going to write block name: " block_name) 67 | ;; (add-to-list 'body-list (concat "message(\"" block_name "\")"));; adding a debug statement for named blocks 68 | ;; ) 69 | (org-back-to-heading t) 70 | (when (looking-at org-outline-regexp) 71 | (goto-char (1- (match-end 0)))) 72 | (when (looking-at (concat " +" org-todo-regexp "\\( +\\|[ \t]*$\\)")) 73 | (setq match_for_TODO_keyword (match-string 1))))) 74 | (unless (or (string= "no" tfile) 75 | (string= "DISABLED" match_for_TODO_keyword) 76 | (not (string= "emacs-lisp" lang))) 77 | (add-to-list 'body-list (concat "\n\n;; #####################################################################################\n" 78 | "(message \"config • " (org-get-heading) " …\")\n\n") 79 | ) 80 | (add-to-list 'body-list body) 81 | )))) 82 | (with-temp-file output-file 83 | (insert ";; ============================================================\n") 84 | (insert ";; Don't edit this file, edit config.org' instead ...\n") 85 | (insert ";; Auto-generated at " (format-time-string current-date-time-format (current-time)) " on host " system-name "\n") 86 | (insert ";; ============================================================\n\n") 87 | (insert (apply 'concat (reverse body-list)))) 88 | (message "—————• Wrote %s" output-file)))) 89 | 90 | 91 | ;; following lines are executed only when my-tangle-config-org-hook-func() 92 | ;; was not invoked when saving config.org which is the normal case: 93 | (let ((orgfile (concat my-user-emacs-directory "config.org")) 94 | (elfile (concat my-user-emacs-directory "config.el")) 95 | (gc-cons-threshold most-positive-fixnum)) 96 | (when (or (not (file-exists-p elfile)) 97 | (file-newer-than-file-p orgfile elfile)) 98 | (my-tangle-config-org) 99 | ;;(save-buffers-kill-emacs);; TEST: kill Emacs when config has been re-generated due to many issues when loading newly generated config.el 100 | ) 101 | (load-file elfile)) 102 | 103 | ;; when config.org is saved, re-generate config.el: 104 | (defun my-tangle-config-org-hook-func () 105 | (when (string= "config.org" (buffer-name)) 106 | (let ((orgfile (concat my-user-emacs-directory "config.org")) 107 | (elfile (concat my-user-emacs-directory "config.el"))) 108 | (my-tangle-config-org)))) 109 | (add-hook 'after-save-hook 'my-tangle-config-org-hook-func) 110 | 111 | (custom-set-variables 112 | ;; custom-set-variables was added by Custom. 113 | ;; If you edit it by hand, you could mess it up, so be careful. 114 | ;; Your init file should contain only one such instance. 115 | ;; If there is more than one, they won't work right. 116 | '(ac-ispell-fuzzy-limit 4) 117 | '(ac-ispell-requires 4) 118 | '(flycheck-checker-error-threshold 4000) 119 | '(org-agenda-files 120 | '("/Users/blaine/gtd/tasks/tasks.org")) 121 | '(package-selected-packages 122 | '()) 123 | '(warning-suppress-types '(((flymake flymake)) ((flymake flymake))))) 124 | 125 | (custom-set-faces 126 | ;; custom-set-faces was added by Custom. 127 | ;; If you edit it by hand, you could mess it up, so be careful. 128 | ;; Your init file should contain only one such instance. 129 | ;; If there is more than one, they won't work right. 130 | '(mode-line ((t (:foreground "#030303" :background "#bdbdbd" :box nil)))) 131 | '(mode-line-inactive ((t (:foreground "#f9f9f9" :background "#666666" :box nil))))) 132 | 133 | ;; ;; load org package and our emacs-config.org file 134 | ;; (use-package org 135 | ;; :ensure t 136 | ;; :config 137 | ;; (org-babel-load-file "~/.emacs.d/configuration.org")) 138 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Version](https://img.shields.io/static/v1?label=configorg&message=0.2&color=brightcolor) 2 | [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) 3 | 4 | 5 | # Blaine's initialization file for Emacs 6 | 7 | ## What is this? 8 | 9 | This repo contains my defualt Emacs cofiguration file, `config.org`, that is written in org-mode. 10 | GitHub can render org-mode in the web browser. 11 | Click in the config.org file above to render it like GitHub markdown. 12 | 13 | `config.org` is a literate programming document with code blocks of elisp code flanked by prose. 14 | On startup, the code is stripped out of `config.org` and written to `config.org`, which Emacs then reads to configure it. 15 | 16 | ## Introduction to Emacs 17 | 18 | Emacs is a text editor primarily used to create document files and computer code source files. 19 | Emacs can also do other tasks like reading e-mail and browsing the web. 20 | The org-mode package also supports project planning via its strong support for making lists and outlines. 21 | The org-agenda package supports the scheduling of tasks and has been widely used to deploy the *Getting Things Done* (GTD) approach to time management. 22 | The org-roam package is popular for knowledge management using the zettelkasten method of note-taking. 23 | 24 | You can also read e-mail and RSS feeds and browse the web from Emacs. 25 | Some people spend all day working in Emacs. 26 | You can do so much in Emacs that it has been likened to an operating system. 27 | 28 | ## Emacs is highly configurable 29 | 30 | Emacs is the ultimate configurable text editor. 31 | The Emacs Lisp (elisp)language allows users to develop highly customized editors. 32 | The customization is in the form of settings and functions. 33 | Often, related settings and functions are bundled into packages. 34 | 35 | The configuring process can be an infinitely deep rabbit hole. 36 | The process of configuring Emacs is never finished, only momentarily paused. 37 | 38 | Emacs was designed to be a software toolkit for building extensions to the base text editor. 39 | These applications are written in elisp and are shared as packages. 40 | ELisp is a variant of LISP, which stands for list processing. 41 | LISP was the second major programming language developed shortly after the first version of FORTRAN in the 1950s. 42 | Elisp descended from MacLisp (which is not related to Mac computers) in the 1970s and emerged about the same time as common lisp. 43 | 44 | Elisp has been customized for programming text editors like Emacs. 45 | Most of the the Emacs code base is written in elisp with a small percentage written in C for speed. 46 | The elisp compiler cannot handle parallel processing, so elisp is unsuitable as a modern multipurpose programming language. 47 | However, the core Emacs developers and package developers have extensively optimized the performance of elisp. 48 | Although you can run small programs written in elisp outside of Emacs, you may be better off using Clojure, Common Lisp, Racket, or Scheme for general programming. 49 | Learning LISP is a common way to become a better programmer in general. 50 | 51 | 52 | ## Text editing 53 | 54 | Emacs has highly developed support for editing plain text, LaTeX, asciidoc, markdown, RestructuredText, HTML, org-mode, and other kinds of text files. 55 | This support includes autocompletion, access to Grammarly for several document types and snippets, and access to several [Language Server Protocols, LSPs](https://microsoft.github.io/language-server-protocol/). 56 | 57 | Text file editing can be divided into two eras: before LSPs and after LSPs. 58 | LSPs are a central feature of modern Integrated Development Environments (IDEs). 59 | There is also support for managing citations via BibTex and reading PDFs and ebooks inside of Emacs. 60 | 61 | ## Advice for Beginners 62 | 63 | Unfortunately, premature configuration of Emacs is a common source of premature frustration for beginning users of Emacs. 64 | It is best to use the GUI version of Emacs first and use the pull-down menus to do productive writing in Emacs as soon as possible to avoid getting frustrated. 65 | The value of the pull-down menus is underemphasized, with new users prematurely directed to using the keyboard shortcuts. 66 | However, the pull-down menus have many of the capabilities found in the pulldowns of other text editors. 67 | After you are comfortable with basic writing and editing tasks, you can start learning keyboard shortcuts or key bindings. 68 | Then start to configure your Emacs profile file. 69 | 70 | ## Editing Textbox on webpages inside Emacs 71 | 72 | The edit-server package enables you to edit text areas in webpages using Emacs. 73 | Likewise, the atomic-chrome enables you to do so via the GhostText plugin for Chrome. 74 | You click on the ghost icon in your browser's toolbar to send the text to Emacs. 75 | You can then edit the text with the full power of Emacs's editing features. 76 | The changed text is updated immediately in the text area on the webpage. 77 | This capability works with Overleaf, the website for editing LaTeX documents on the web. 78 | It also works in the code cells of Jupyter notebooks. 79 | I talked about this [topic](https://github.com/MooersLab/DSW22ghosttext) in July 2022. 80 | *Atomic-chrome* can be configured to enter the *latex-mode* whenever invoked from Overleaf. 81 | 82 | 83 | ## Programming in Emacs 84 | 85 | Emacs is also a software-integrated development environment (IDE). 86 | It supports syntax highlighting, code snippets, and autocompletion for many programming languages. 87 | 88 | Emacs also supports several approaches to literate programming. 89 | One of the most developed approaches is in org-mode where the `emacs-jupyter` package enables you to tap into your Jupyter Notebook kernels to access scores of programming languages. 90 | You can switch kernels between code blocks inside one org document and thereby do polyglot literate programming. 91 | 92 | The package *emacs-jupyter* package can be hard to configure and use correctly. 93 | Similar capabilities are available from *org-babel* via *ob-jupyter*. 94 | Just list `jupyter` last in the list of org-babel languages. 95 | Use `jupyter` for the language in the code block header and then select the appropriate Jupyter kernel to select the language you want to use. 96 | 97 | 98 | ![Figure 1](https://github.com/MooersLab/configorg/blob/main/emacs-learning-curve.jpg) 99 | 100 | Emacs is a configurable workspace in addition to being an editor. 101 | You can do most of your computing tasks inside of Emacs. 102 | Emacs is almost an operating system. 103 | You can replicate your Emacs configuration on Windows, Mac, Linux, and BSD to maintain a uniform working environment regardless of the underlying operating system. 104 | 105 | ## Emacs 29.0.5 106 | 107 | Since January 2022, it has the startup flag `--init-directory` that enables easy switching between start-up profiles. 108 | This has displaced my use of chemacs, which is described in the section below. 109 | If you use an earlier version of Emacs, you can use this `config.org` file with *chemacs2*. 110 | 111 | I use bash aliases to start *Emacs* with specific profiles and with or without the /--init-debug/ flag. 112 | For example, I enter `eid` to launch Emacs version 29.0.5 with the default profile (i.e., the profile tangled from the config.org file). 113 | These are defined in a `.bashAppAliases` file that I source from my `.zshenv` file which is in turn sourced from my `.zshrc` startup file. 114 | 115 | ```bash 116 | alias eib='/Applications/Emacs29.0.5.app/Contents/MacOS/Emacs --init-directory ~/emacs-brave' 117 | alias eibd='/Applications/Emacs29.0.5.app/Contents/MacOS/Emacs --init-directory ~/emacs-brave --debug-init' 118 | 119 | alias eic='/Applications/Emacs29.0.5.app/Contents/MacOS/Emacs --init-directory ~/crafted-emacs' 120 | alias eicd='/Applications/Emacs29.0.5.app/Contents/MacOS/Emacs --init-directory ~/crafted-emac --debug-init' 121 | 122 | alias eid='/Applications/Emacs29.0.5.app/Contents/MacOS/Emacs --init-directory ~/.emacs.default' 123 | alias eidd='/Applications/Emacs29.0.5.app/Contents/MacOS/Emacs --init-directory ~/.emacs.default --debug-init' 124 | 125 | alias eidm='/Applications/Emacs29.0.5.app/Contents/MacOS/Emacs --init-directory ~/doom-emacs' 126 | alias eidmd='/Applications/Emacs29.0.5.app/Contents/MacOS/Emacs --init-directory ~/doom-emac --debug-init' 127 | 128 | alias eie='/Applications/Emacs29.0.5.app/Contents/MacOS/Emacs --init-directory ~/ess-emacs' 129 | alias eied='/Applications/Emacs29.0.5.app/Contents/MacOS/Emacs --init-directory ~/ess-emacs --debug-init' 130 | 131 | alias eil='/Applications/Emacs29.0.5.app/Contents/MacOS/Emacs --init-directory ~/latex-emacs' 132 | alias eild='/Applications/Emacs29.0.5.app/Contents/MacOS/Emacs --init-directory ~/latex-emacs --debug-init' 133 | 134 | alias eis='/Applications/Emacs29.0.5.app/Contents/MacOS/Emacs --init-directory ~/scimax' 135 | alias eisd='/Applications/Emacs29.0.5.app/Contents/MacOS/Emacs --init-directory ~/scimax --debug-init' 136 | ``` 137 | 138 | 139 | 140 | ## My fling with chemacs 141 | 142 | I changed my setup in January 2022. 143 | I switched to using the *chemacs.el* package to swap emacs configurations on the fly. 144 | I set up aliases to commands to use alternate configurations. 145 | For example, I enter the alias *e29r* to fire up Emacs 29 with Dave Wilson's rational-emacs configuration. 146 | The `e29b` alias is used to fire up Emacs 29 with the brave-emacs configuration from the GitHub site of the Emacs configuration recommended by [[https://github.com/flyingmachine/emacs-for-clojure/][Daniel Higginbotham]], the author of [[https://www.braveclojure.com/][*Clojure for the Brave and True*]]. 147 | The `e29m` alias fires up Emacs29 with the `mar30-emacs` configuration, which rebuilds my default configuration using the files pulled from GitHub. 148 | The `mar30-emacs` configuration starts without errors and works better than before. 149 | Some of the prior package configurations have been commented out. 150 | I will fix them when time permits. 151 | 152 | The current *init.el* file is configured with the current default Emacs directory as being *~/mar30-emacs*. 153 | You will 154 | In my home directory, I stored my aliases in the hidden file *.bashAppAliases*. 155 | They fire up GNU Emacs with the GUI. 156 | Change the aliases to start Emacs in the terminal by adding the ~-nw~ flag. 157 | I source this file from my *.zshenv* file.: 158 | 159 | ```bash 160 | alias e29='/Applications/Emacs.app/Contents/MacOS/Emacs' 161 | alias e29b='/Applications/Emacs.app/Contents/MacOS/Emacs --with-profile brave' 162 | alias e29m='/Applications/Emacs.app/Contents/MacOS/Emacs --with-profile mar30' 163 | alias e29r='/Applications/Emacs.app/Contents/MacOS/Emacs --with-profile rational' 164 | ``` 165 | 166 | I surrendered the */Users/blaine/.emacs.d* directory to */chemacs.el/*. 167 | 168 | 169 | I store the profiles for the alternate Emacs configurations in *~/.emacs-profiles.el*, which has the following elisp content: 170 | 171 | ```bash 172 | (("default" . ((user-emacs-directory . "~/.emacs.default"))) 173 | ("brave" . ((user-emacs-directory . "~/.brave-emacs"))) 174 | ("mar30" . ((user-emacs-directory . "~/.mar30-emacs"))) 175 | ("rational" . ((user-emacs-directory . "~/.rational-emacs")))) 176 | ``` 177 | 178 | I store of my copy of this repository in */Users/blaine/.emacs.default/configorg*. 179 | I then made an bash alias called *gitpull* that pulls from the GitHub repo and copies the new version to the directory above. 180 | This copy is the file that Emacs reads. 181 | 182 | ```bash 183 | gitpull='git pull && cp config.org ../.' 184 | ``` 185 | 186 | I also made an alias to switch to this folder when needed: 187 | 188 | ```bash 189 | ghcon='cd ~/.emacs.default/ghconfigorg' 190 | ``` 191 | 192 | ## Keep it simple 193 | 194 | In July 2021, I streamlined my configuration by removing about half of the context. 195 | I found that moving all of my workflows to Emacs was too big of a step. 196 | I am not quite advanced of an Emacs user to do everything Emacs. 197 | 198 | I am reverting to several of my prior workflows with other software that worked well for me. 199 | For example, I maintain a diary in an Overleaf in LaTeX. 200 | I used the journal feature of org-mode for several months. 201 | I found myself converting the org entries to LaTeX and pasting them into Overleaf every day. 202 | This was too much extra work. 203 | If it is not broken, do not fix it. 204 | 205 | I moved the inventory of my projects and folders from proj.org file to Google Sheets. 206 | I accidentally deleted too many subtrees in the proj.org file that I used to track my projects. 207 | I could have solved this problem by keeping proj.org under version control with git. 208 | I am now using the Google Sheets workbook to look up projects and tasks.org to work with projects in the agenda. 209 | I no longer need proj.org. 210 | 211 | I am trying to limit my use *Emacs* to do the following activities: 212 | 213 | - Editing LaTeX, markdown, and org files with Grammarly running 214 | - Read epub and PDF documents and capture notes as I read 215 | - Time management with org-agenda 216 | - Literate programming in org 217 | - Exploring Clojure with using cider or the simpler *M-x inf-clojure* 218 | - Using Emacs as an IDE to develop code for the following languages: 219 | - C++ 220 | - C 221 | - Clojure 222 | - Common Lisp 223 | - csharp 224 | - fsharp 225 | - HTML 226 | - JavaScript 227 | - Python 228 | - R 229 | - scala 230 | - Wolfram Language 231 | - Connecting projects with org-roam 232 | - Using ido-mode and dired for directory navigation 233 | - Using Org-ref version 3 to insert citations and to manage BibTeX file 234 | - Access remote computers with tramp 235 | - Use *term* package to run Macport updates 236 | - Use of *elfeed* to do literature searches 237 | - 238 | Once I have mastered Emacs for the above activities, I will consider expanding my use to do the following: 239 | 240 | - advance my use of org-agenda 241 | - expand my use of other features of org 242 | - reading e-mail inside Emacs 243 | - use the time tracking feature with org-capture 244 | - integrate org capture with manual effort tracking 245 | - figure out how to generative time reports from org 246 | - develop a pipeline from Google Sheets projects to prog.org 247 | - make more regular use of the Pomodoro method 248 | - figure out why Magit is so great 249 | - master hydra 250 | 251 | ## Editorial on org-roam 252 | 253 | Org-roam is an exciting project that supports the building of electronic zettelkastens in Emacs using org files as the individual files of the card catalog. 254 | A zettelkasten, or card catalog, is an approach to knowledge management that political scientist Dr. Niklas Luhmann deployed to good effect just before the personal computer era. 255 | The electronic enables making links between entries and powerful searching. 256 | The paper version may be more laborious to maintain but be more effective at generating new connections as you fumble through the card catalog. 257 | The experiment has yet to be done to establish which approach is most effective. 258 | I suspect that both forms require many hours of usage per day to obtain their benefit. 259 | 260 | I have been using (abusing) my zettelkasten by using it as a massive mindmap. 261 | I am a big fan of mindmaps and the *iThoughtsX.app*. 262 | I find mindmaps to be very stimulating and very effective for generating new ideas. 263 | 264 | My zettelkasten is a hierarchical tree that organizes my interests and projects. 265 | It could be thought of as a mindmap of mindmaps. 266 | The *org-roam-ui* enables exploration of the tree in the browser. 267 | You can focus in one subtree at a time. 268 | It is very cool. 269 | 270 | I think that this tree of trees approach might be the best use of org-roam for me. 271 | I have not tried building a mindmap of all of my mindmaps *iThoughtsX*. 272 | I suppose that it would be too unwieldy. 273 | 274 | I see the potential of zettelkastens, but no one has conducted controlled experiments to test whether they really enhance productivity. 275 | Without such experimental data, the zettelkasten movement is running on blind faith. 276 | The same kind of criticism can be made of Emacs. 277 | 278 | 279 | 280 | ## Skill levels 281 | 282 | In the following text, I refer to the following five levels of skill acquisition in the [Dreyfus and Dreyfus model](http://www.dtic.mil/cgi-bin/GetTRDoc?AD=ADA084551&Location=U2&doc=GetTRDoc.pdf). 283 | 284 | - novice 285 | - advanced beginner 286 | - competent user 287 | - proficient user 288 | - expert 289 | 290 | These levels have been very thoughtfully interpreted by Trey Jackson in terms of [Emacs skills](https://softwareengineering.stackexchange.com/questions/38131/emacs-and-self-reinforcing-performance). 291 | 292 | ```bibtex 293 | {@TechReport{Dreyfus1980AFiveStageModelOfTheMentalActivitiesInvolvedInDirectedSkillAcquisition, 294 | author = {Dreyfus, Stuart E and Dreyfus, Hubert L}, 295 | title = {A five-stage model of the mental activities involved in directed skill acquisition}, 296 | institution = {DTIC Document}, 297 | year = {1980}, 298 | annote = {The famous Dreyfus and Dreyfus model of expertise. }, 299 | } 300 | ``` 301 | 302 | 303 | ## My learning Emacs spiral 304 | 305 | My skill levels with Emacs and Vim are in the advanced beginner to competent user range. 306 | I am not a professional programmer; I am an academic scientist. 307 | I am a competent user of bash, Python, R, LaTeX, and Gnuplot (one of the most badly underappreciated plotting programs available). 308 | 309 | I became competent with the basic Vim keybindings before diving into Emacs. 310 | The ability to use Vim keybindings via evil-mode eased adopting Emacs. 311 | However, mastering the Vim key bindings was two weeks of hell. 312 | The Emacs keybindings are easier to pick up if you go slow and easy. 313 | I have stopped using evil-mode and started using the Emacs key bindings. 314 | I try to use Vim several times a week to keep up my Vim skills. 315 | 316 | You can do a lot in your early use of Emacs by using the intuitive pull-down menus. 317 | You can start using Emacs without remembering any key bindings. 318 | Most tutorials start with the key bindings; they should really start with the pull-down menus. 319 | 320 | My study of Emacs has been discontinuous due to the demands of my professional life. 321 | I have to relearn infrequently used commands due to these discontinuities. 322 | I have made a series of [quizzes](https://github.com/MooersLab/qemacs) to improve my recall of the commands. 323 | 324 | I want to take these quizzes on spaced intervals, but I have lacked the time and energy to do so. 325 | Nonetheless, taking the relevant quiz before using some of the related features in Emacs is beneficial. 326 | The quiz takes 5-10 minutes and refreshes the recall of the relevant commands. 327 | Taking the quiz is a faster and more effective way to refresh your recall of the commands than searching the World Wide Web, which takes much longer than most people will admit. 328 | 329 | I also found it less frustrating to start with bare-bones GNU Emacs than with pre-configured alternatives (e.g., Doom, Spacemacs, SciMax) loaded with advanced features. 330 | Spacemacs might be best suited for advanced Vim users and other professional developers familiar with similar advanced features in IDEs and expect these advanced features. 331 | After I master Emacs Lisp, I plan to study the preconfigured variants for ideas about how to improve my configuration for GNU Emacs. 332 | 333 | I have bounced off Emacs several times over the past three years, but I have used Emacs every day for the past twelve months. 334 | I want to make Emacs my primary editor because I can configure it into an almost complete work environment that reduces context switching. 335 | However, building that environment seems to be a perpetual work in progress. 336 | It is the ultimate editor in that no one is more highly configurable. 337 | You will never want to switch to another editor, although it may be more efficient to do so for a short while with specialized IDEs for certain kinds of programming tasks. 338 | 339 | You can do a lot with the base installation of Emacs, but you will invariably be lured into adding packages to extend It. 340 | There are over 5,000 packages available for Emacs. 341 | Many have overlapping functionality and objectives. 342 | If there are only 2,000 unique objectives, there are 2,000 reasons to use Emacs. 343 | Limitations on your mental bandwidth will constrain you to use about a tenth of what is available. 344 | 345 | When starting with Emacs, I recommend limiting yourself to one feature you can use in your daily workflow. 346 | By meeting a need in your life with Emacs, you will start to build a commitment to learning more. 347 | Your needs are unique to you, so you will have to design your own learning spiral. 348 | 349 | For example, a good place to start might be using it to write simple AAAreadme.txt or AAAreadme.md files for coding projects. 350 | Once you become comfortable with the basic editing tasks, you can start writing org documents. 351 | Org is a supercharged markdown variant that recognizes LaTeX, so it is easy to overcome the limitations of most markdown variants. 352 | An org file can be exported to a wide variety of document types. 353 | Then, you can start using one of the major modes for writing computer programs, or, if you are not a programmer, you might start to explore using an org-agenda to organize your life. 354 | 355 | A hard lesson that I keep relearning is not to overdo it by trying to move all of my workflows into Emacs. 356 | Just move one workflow at a time when it makes sense to do so. 357 | The features that get you hooked may not be the ones you anticipate. 358 | 359 | 360 | 361 | ## .emacs or init.el or config.org 362 | 363 | The emacs initialization file contains the settings for parameters for various packages and functions. 364 | It is written in Emacs Lisp or elisp. 365 | Emacs has to read these settings to load the plugins or packages that you want to use. 366 | You can use Emacs without a configuration file and the extra capabilities the packages provide, but it will be a less powerful experience. 367 | 368 | You can store your configuration in an *.emacs* file that resides in the top directory. 369 | Emacs reads this startup file. 370 | The home directory is a convenient location to access the file quickly for editing. 371 | The hiding of the file by starting the file name with a period is to hinder you from deleting the file by accident. 372 | I keep this file under version control with git. 373 | 374 | You can also store your configuration in an init.el file in the *~/.emacs.d* directory. 375 | The format and content are identical to the *.emacs* file. 376 | 377 | Another approach from Derek Taylor is to have some key settings from the package repositories in the `init.el` file 378 | and then place the remaining settings in a *config.org* file. 379 | The *config.org* file is an org-mode file with the settings in elisp code blocks. 380 | You can annotate the file with explanatory text outside of the code blocks. 381 | The explanatory text can contain special instructions about the installation of the package 382 | or it can highlight important keybindings. 383 | You can add tables and even embed images. 384 | 385 | The elisp code in the code blocks is extracted (tangled) into a *config.el* file when Emacs starts up. 386 | The code enabling this magic resides in the *init.el* file. 387 | The *init.el* file must be present with the *config.org* file in the *.emacs.d* directory. 388 | I put the *config.org* and *init.el* files under version control because I occasionally break them. 389 | 390 | My main source of discouragement with Emacs was the frequent breaking of my *.emacs* or *init.el* file. 391 | This usually happens after pasting settings copied from someone else's configuration file without fully understanding the settings. 392 | This is a really bad idea for novices, but it is very tempting to do so. 393 | 394 | Storing most of the settings in code blocks in the *config.org* file reduces the temptation to copy large code blocks from someone else's config file. 395 | This, in turn, dramatically reduced the frequency of the breaks and thus reduced my frustration caused by these breaks. 396 | 397 | 398 | ## Advantages of the config.org file 399 | 400 | Using the org file for the configuration has at least four advantages. 401 | 402 | First, the settings are in elisp code blocks. 403 | You store comments and notes in the main text outside the code blocks. 404 | 405 | Second, the org-mode file allows the hierarchical organization of the code blocks into sections and subsections. 406 | The sections can be folded while editing the file. 407 | The entire document can be visible in one screen window when all sections are folded. 408 | 409 | Third, the org file is automatically rendered nicely by GitHub. 410 | The preview on GitHub also renders the org file, so you can check the beautifully rendered version as you edit it. 411 | 412 | Fourth, I have an easier time spotting errors in the rendered version of the org file. 413 | 414 | ## Emacs tangles on startup 415 | 416 | On startup, Emacs strips out (tangles) the emacs-lisp code and writes it to a *config.el* file. 417 | This literate programming process is called *tangling*. 418 | The *config.el* file is the file that Emacs uses for its configuration. 419 | The *config.el* file will be written to your Emacs directory, (aka *~/.emacs.d*). 420 | 421 | You still need some settings in your `init.el` file including one that calls *config.org*. 422 | I used a function to do so. 423 | I obtained this function from Karl Voit. 424 | This function is supposed to load the code chunks more rapidly. 425 | 426 | I added the DISABLED tag to some code chunks not to load the code to save time. 427 | My *config.org* file is now over 2700 lines long. 428 | My *config.el* file is about 1000 lines long. 429 | Emacs takes 3-5 seconds to load. 430 | 431 | 432 | ## Instant access to Emacs via the emacsclient 433 | 434 | For instant access to Emacs, launch the emacsclient as a daemon and tap into this daemon. 435 | This procedure is outlined in the [documentation](https://www.emacswiki.org/emacs/EmacsClient). 436 | I currently do not use the daemon and just keep Emacs open for days on end. 437 | 438 | First add, the following to the `config.org` file: 439 | 440 | ```elisp 441 | (server-start) 442 | ``` 443 | 444 | Next, start GNU Emacs version 29 in the GUI using       445 | 446 | ```bash 447 | /Applications/Emacs.app/Contents/MacOS/Emacs --daemon 2>&1 < ~/emacsclient.log & 448 | ``` 449 | Your `config.org` gets tangled at the start of the daemon. 450 | If you edit the `config.org` file, you may need to restart the daemon before your edits can take effect. 451 | 452 | I added the following settings to my *.zshrc* file so that I could use the GUI when launching Emacs. 453 | Set the first option in line two to *-t* to run Emacs in the terminal. 454 | 455 | ```bash 456 | export ALTERNATE_EDITOR="" 457 | export EDITOR="emacsclient -c" # $EDITOR opens in terminal 458 | export VISUAL="emacsclient -c -a /Applications/Emacs.app/Contents/MacOS/Emacs" # $VISUAL opens in GUI mode 459 | ``` 460 | 461 | I made an alias called ec29 for emacsclient for version 29. 462 | 463 | ```bash 464 | alias e29c="echo 'Must have launched daemon with /Applications/Emacs.app/Contents/MacOS/Emacs --daemon' && emacsclient -c -a /Applications/Emacs.app/Contents/MacOS/Emacs" 465 | ``` 466 | 467 | After sourcing this file containing the alias, enter *e29c &* to open a frame on the running Emacs daemon. 468 | This enables instant access to the GNU Emacs GUI. 469 | 470 | When your Emacs session is finished, close the Emacs frame with the command *C-x 5 0*. 471 | 472 | To find the daemon, enter in the terminal: 473 | 474 | ```bash 475 | pgrep -l Emacs 476 | ``` 477 | 478 | To kill the daemon, enter the following command in the terminal: 479 | 480 | ```bash 481 | pkill Emacs 482 | ``` 483 | 484 | To make the daemon permanent, see the documentation for [platform specific](https://www.emacswiki.org/emacs/EmacsAsDaemon) instructions. 485 | 486 | For Mac OSX, make the following file called `gnu.emacs.daemon.plist`: 487 | 488 | ```xml 489 | 490 | 492 | 493 | 494 | Label 495 | gnu.emacs.daemon 496 | ProgramArguments 497 | 498 | /Applications/Emacs.app/Contents/MacOS/Emacs 499 | --daemon 500 | 501 | RunAtLoad 502 | 503 | ServiceDescription 504 | Gnu Emacs Daemon 505 | 506 | 507 | ``` 508 | 509 | Store this file in the following directory: 510 | 511 | ```bash 512 | ~/Library/LaunchAgents 513 | ``` 514 | 515 | Launch the daemon with the following command. 516 | 517 | ```bash 518 | launchctl load -w ~/Library/LaunchAgents/gnu.emacs.daemon.plist 519 | ``` 520 | 521 | ### Server shutdown 522 | 523 | Stop the Emacs daemon from within Emacs with `kill-emacs` or `save-buffers-kill-emacs` in Emacs. 524 | A fancier approach that queries the user about saving open buffers is to add the following to the config.org file. 525 | 526 | ```bash 527 | ;; define function to shutdown emacs server instance 528 | (defun server-shutdown () 529 | "Save buffers, Quit, and Shutdown (kill) server" 530 | (interactive) 531 | (save-some-buffers) 532 | (kill-emacs) 533 | ) 534 | ``` 535 | Use it by entering `M-x server-shutdown`. 536 | 537 | After all of this trouble, I have to admit that I am not using the server very often. 538 | It takes some practice to master managing the server properly and it is a bit of a hassle to shut it down and restart between updates to the configuration file. 539 | 540 | ## Zsh emacs plugin 541 | 542 | There is a *emacs* plugin for zsh that I added to my list of *oh-my-zsh* plugins in my *.zshrc*. 543 | I am not sure that it is doing anything. 544 | 545 | ## Lazy alternative 546 | 547 | Another approach is to leave Emacs running until the next restart of your computer. 548 | Some people have had Emacs sessions run for many weeks or even months. 549 | 550 | ## Further learning resources 551 | 552 | ### The built-in documentation 553 | 554 | Emacs has an enormous amount of documentation available in-line. 555 | Once you develop the habit of using the built-in documentation, it will meet most of your needs. 556 | Enter *C-h ?* to see a list of all the options in the '*Metahelp buffer*'. 557 | You can waste an enormous amount of time by avoiding the built-in documentation. 558 | After years of using Google to look at almost everything, developing the habit of using the built-in documentation takes some effort. 559 | 560 | **Tip:** Enter *C-h k* and select a pull-down menu option to open the corresponding documentation in a new buffer. 561 | 562 | ### elfeed 563 | 564 | This feed service contains thoughtful posts of tips that can improve your use of Emacs. 565 | See the `E/elfeed' section of the config.org file. 566 | 567 | ### IRC channel 568 | 569 | IRC == Internet Relay Channel. 570 | These are popular with Emacs users. 571 | The conversations appear in Emacs. 572 | There is a beginner's channel. 573 | 574 | *ERC* is a popular *IRC* client for Emacs. 575 | 576 | ### Slack RSE emacs channel (M-x research) 577 | 578 | RSE == Research Software Engineer. 579 | A Research Software Engineer is anyone who writes code in research labs. 580 | There is an international society. 581 | I joined the British branch before being aware of the US-RSE, which I subsequently joined. 582 | The M-x research group in the RSE slack channel meets on the first and third Tuesday of every month. 583 | Past presentations are posted [here](https://m-x-research.github.io/). 584 | In the past year, Jen Jensen has been giving a series of lectures on functional programming in Emacs and Common Lisp. 585 | 586 | ### Discord System Crafters Server 587 | 588 | 589 | ### Emacs conferences 590 | 591 | Since the 2019 conference, the conference was virtual but also global. 592 | Each talk was prerecorded and then transcribed. 593 | Each talk has a webpage with the transcript's text, a summary of the discussion, and a link to the video. 594 | Most talks were short so they offer a great way to learn what is available in Emacs. 595 | The transcripts and links provide gateways to deeper learning. 596 | Only videos are available from the 2013 and 2015 conferences. 597 | 598 | * [Emacsconf2021](https://emacsconf.org/2021/) 599 | * [Emacsconf2020](https://emacsconf.org/2020/) 600 | * [Emacsconf2019](https://emacsconf.org/2019/) 601 | * [Emacsconf2015](https://emacsconf.org/2015/videos/) 602 | * [Emacsconf2013](https://emacsconf.org/2013/) 603 | 604 | 605 | ### YouTube series 606 | These can be useful for raising your awareness of packages that are not covered in the books below. 607 | However, the videos can be frustrating when the presenter moves too fast over the keybindings that they are using. 608 | In general, a novice's return on investment may be lower than expected. 609 | Your time is better spent reading the books listed below and the in-line documentation. 610 | 611 | My recommendation is to start with Kauffman's tool session. 612 | It will get you going in 2-3 hours. 613 | Then to take your skills to the next level, I recommend the System Crafters series. 614 | 615 | * [Kauffman's tool session on Emacs, part 1](https://www.youtube.com/watch?v=HyMCzEwI4cU&t=2857s) 616 | * [Kauffman's tool session on Emacs, part 2](https://www.youtube.com/watch?v=7ReBnH0MalQ) 617 | * [System Crafters (Dave Wilson)](https://www.youtube.com/c/SystemCrafters) 618 | * [System Crafters on Github (for better list of links to videos)](https://github.com/daviwil/emacs-from-scratch) 619 | * [Protesilaos (a.k.a Prot) Stavrou: Emacs mindset and Unix philosophy](https://www.youtube.com/watch?v=qTncc2lI6OI) 620 | * [Moral lessons from switching to Emacs](https://www.youtube.com/watch?v=gwT5PoXrLVs) 621 | * [Protesilaos Stavrou Playlist](https://www.youtube.com/c/ProtesilaosStavrou/videos?view=0&sort=dd&shelf_id=0) 622 | * [Andrew Tropin](https://www.youtube.com/channel/UCuj_loxODrOPxSsXDfJmpng) 623 | * [Xah Lee](https://www.youtube.com/channel/UCXEJNKH9I4xsoyUNN3IL96) 624 | * [Sacha Chua](https://www.youtube.com/channel/UClT2UAbC6j7TqOWurVhkuHQ) 625 | * [Emacs Elements by Raoul Comninos](https://www.youtube.com/channel/UCe5excZqMeG1CIW-YhMTCEQ) 626 | * [Emacs: fuzzy find files (fzf, ripgrep, Ivy+Counsel)](https://www.youtube.com/watch?v=IDkx48JwDco) 627 | * [An Ivy, Swiper, & Counsel tutorial for Emacs Noobs](https://www.youtube.com/watch?v=AaUlOH4GTCs&t=876s) 628 | * [Mike Zamansky: Using Emacs Series 75 episodes from a computer science professor](https://cestlaz.github.io/stories/emacs/) 629 | * [Using OrgMode to organize your life, Rainer König, 40 short videos](https://www.youtube.com/watch?v=sQS06Qjnkcc&list=PLVtKhBrRV_ZkPnBtt_TD1Cs9PJlU0IIdE) These are in small bits and are highly accessible. 630 | 631 | 632 | 633 | ### Websites 634 | 635 | * [Prot's superduper config.org file](https://gitlab.com/protesilaos/dotfiles/-/blob/master/emacs/.emacs.d/prot-emacs.org) 636 | * [zsh Emacs plugin](https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/emacs) 637 | * [Getting Things Done with Org-mode](https://lucidmanager.org/productivity/getting-things-done-with-emacs/) 638 | * [Org-Mode](http://doc.norang.ca/org-mode.html) 639 | * [Customize zsh](https://brandon.azbill.dev/how-to-customize-your-zsh-terminal) 640 | 641 | 642 | ### GTD in org-mode 643 | 644 | * [Org Mode - Organize Your Life In Plain Text!](http://doc.norang.ca/org-mode.html) 645 | * [Orgmode for GTD, Nicolas Petton](https://emacs.cafe/emacs/orgmode/gtd/2017/06/30/orgmode-gtd.html) 646 | 647 | 648 | ### Books 649 | 650 | Perhaps because of the self-documenting nature of Emacs, there are not many books about Emacs. 651 | In contrast, there are three times as many books about Clojure, a language with a smaller user base and a third of the lifespan. 652 | 653 | Anyways, several of the books listed below are available in electronic form inside Emacs. 654 | The initial banner package will take you to this documentation as will the *C-h ?*. 655 | 656 | While traveling up the Emacs learning spiral, I would read these books in the following order. 657 | 658 | 659 | #### [Harley Hahn's Emacs Field Guide](http://www.harley.com/emacs/) 660 | 661 | The author recommends reading his book before taking the in-line Emacs tutorial. 662 | Emacs greybeards may differ in opinion on this matter. 663 | 664 | Nonetheless, Hahn wrote this book for people with no experience with computing. 665 | Most graduate students in the biological sciences (outside of bioinformatics and computational biology) would benefit from reading the first several chapters to better understand their computers. 666 | 667 | The author has written several technical books about Unix-like operating systems and is an excellent writer. 668 | Skip this book if you are already a competent user of Emacs. 669 | 670 | #### [Learning GNU Emacs, 3rd edition, 2004](https://www.oreilly.com/library/view/learning-gnu-emacs/0596006489/) 671 | 672 | A team of five authors wrote this book. 673 | The first edition appeared in 1991, so the authors had over a decade to improve the text. 674 | I think that it is well written. 675 | The authors strove to make the book accessible. 676 | 677 | Nonetheless, I suspect that readers should have some experience with Emacs. 678 | If you are a novice user, internalize the content of chapters 1 and 2 as recommended by the authors. 679 | If you struggle with the first two chapters, read the above book by Hahn. 680 | 681 | *Learning GNU Emacs* will move advanced beginners to the competent-user level despite lacking coverage of some currently popular packages. 682 | The book is 509 pages; nonetheless, the content is not too lengthy or deep. 683 | 684 | Even though I have been using Emacs off and on for three years, I first learned about bookmarks from this book. 685 | Bookmarks combined with the recent dashboard package make a fast way to resume unfinished work. 686 | This book is useful for filling holes in your knowledge that are bound to exist if you have neglected to read the official documentation. 687 | 688 | The third edition of the book was published before Git and Org became widely used, so the version control and outline-mode chapters are outdated. 689 | Of course, it also does not cover the Language Server Protocols (LSPs) that empower modern autocompletion. 690 | LSPs are the most beneficial advance in text editors in the past decade. 691 | 692 | Although the book is almost two decades old, more than 95% of the commands in it still work. 693 | After mastering the content of this book, you will understand most of the features of Emacs, and you will be well-prepared to master more advanced topics. 694 | I recommend reading it as a second book because only chapters 1 and 2 overlap with Hahn's book. 695 | 696 | 697 | #### [Org Mode Compact Guide, version 9.5, 2021, The Org Mode Developers](https://orgmode.org/guide/) 698 | 699 | Org-mode is a significant draw to Emacs for non-programmers and programmers alike. 700 | Org has many features, some of which appeal to different audiences. 701 | 702 | Org-mode has come to dominate Emacs over the past decade, so it is easy to forget that you can be productive in Emacs without ever using Org. 703 | In a sense, you can view Org as a fork on the Emacs learning spiral. 704 | 705 | This guide is a concise introduction to the essentials of Org-Mode. 706 | It is 29 pages long. 707 | 708 | 709 | #### [Org Mode Manual, online version 9.5, 2021, The Org Mode Developers](https://orgmode.org/manual/) 710 | 711 | This manual is more readable than it appears from its cover. 712 | Nonetheless, Org still needs a more accessible book for beginners. 713 | 714 | #### [GNU EMacs Manual, 19th Edition, 2021, Stallman et al.](https://www.gnu.org/software/emacs/manual/emacs.html) 715 | 716 | This manual is readable. 717 | Its content is similar to that of Cameron et al., but it is current. 718 | The book is not illustrated and does not cover the pull-down menus. 719 | The authors deemed these to be self-explanatory. 720 | I recommend reading it after reading Cameron et al. 721 | 722 | #### [Mastering Emacs, 2nd Edition, 2020, Micky Petersen](https://www.masteringemacs.org/) 723 | 724 | Read this book if you are a frustrated or impatient advanced beginner who has not been able to progress with the last two books. 725 | The author presents his approach to mastering Emacs without using much of the official documentation. 726 | Also, read this book to learn about the features of popular packages that make Emacs competitive with Microsoft's rapidly advancing Visual Studio Code editor. 727 | You will eventually have to return to the last two books to fill holes in your knowledge. 728 | The author has almost two decades of experience in Emacs. 729 | 730 | #### [An Introduction to Programming in Emacs Lisp by Robert Chassell](https://www.gnu.org/software/emacs/manual/eintr.html) 731 | 732 | This book is a must-read unless you are already a master of Emacs Lisp. 733 | Eventually, you must learn Emacs Lisp to understand the code in your Emacs configuration file. 734 | Fortunately, that is not as hard to do as you may think because the author wrote this book for non-programmers. 735 | 736 | Emacs Lisp is a fine first programming language to learn because, unlike most other programming languages, it allows you to write executable code in only one line. 737 | In addition, you can enter *C-j* to the right of the code in any Emacs buffer, and Emacs returns the result on the line below. 738 | You can save the buffer to a file on your hard drive. 739 | In other words, you can execute the code examples from the book interactively and retain a copy of your work in a document for later reference. 740 | This interactive feature of elisp invites exploring what the code can do beyond the examples in the book. 741 | 742 | Alternatively, you can place the cursor after the closing parenthesis of an elisp expression and enter *C-x C-e* to execute the code. 743 | This is a great way to test new code for the configuration file without restarting Emacs. 744 | This interactivity is a blast! 745 | 746 | You might find the book too slow and tedious if you are already a Lisp programmer. 747 | If not but you are a programmer, do not try to read the book without working through the code in an open session of Emacs. 748 | If you do, you will get bored by page 50 and abandon reading the rest of the book. 749 | 750 | This book was first released in 1991 and has been updated with most updates of Emacs. 751 | It was last updated in 2021 for Emacs 27.2. 752 | This is one of the best-written computer books that I have encountered. 753 | It is wonderful that it is available for free. 754 | 755 | #### [Writing GNU Emacs Extensions by Robert Glickstein, 1997, O'Reilly & Associates](https://www.oreilly.com/library/view/writing-gnu-emacs/9781449395056/) 756 | 757 | This book assumes more prior knowledge of Emacs than the book by Chassell. 758 | It is accessible to advanced beginners with Emacs. 759 | It aims to prepare you to write a minor mode in Emacs Lisp. 760 | Although the book is a quarter-century old, most of the code still works. 761 | I recommend reading it after completing the book by Chassell. 762 | 763 | #### [Hacking your way around in Emacs by Marcin Borkowski](https://leanpub.com/hacking-your-way-emacs/) 764 | 765 | This is a self-published book for intermediate users of Emacs Lisp. 766 | The first chapter is free. 767 | The book has three chapters. 768 | 769 | #### [GNU Emacs Lisp Reference Manual by Bill Lewis et al.](https://www.gnu.org/software/emacs/manual/eintr.html) 770 | 771 | This book is a reference manual, but it is remarkably well-written. 772 | It is an excellent supplemental source while reading the book by Chassell. 773 | Competent users who want to become proficient users need to read this book. 774 | 775 | ## Update history 776 | 777 | |Version | Changes | Date | 778 | |:-----------:|:------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------:| 779 | | Version 0.2 | Added badges, funding, and update table. | 2024 May 21 | 780 | 781 | 782 | ## Sources of funding 783 | 784 | - NIH: R01 CA242845 785 | - NIH: R01 AI088011 786 | - NIH: P30 CA225520 (PI: R. Mannel) 787 | - NIH: P20 GM103640 and P30 GM145423 (PI: A. West) 788 | 789 | -------------------------------------------------------------------------------- /emacs.el: -------------------------------------------------------------------------------- 1 | ;; Start the emacs-client server 2 | 3 | ;; (server-start) 4 | 5 | ;; 6 | (require 'package) 7 | 8 | (defmacro append-to-list (target suffix) 9 | "Append SUFFIX to TARGET in place." 10 | `(setq ,target (append ,target ,suffix))) 11 | 12 | (append-to-list package-archives 13 | '(("melpa" . "http://melpa.org/packages/") ;; Main package archive 14 | ("melpa-stable" . "http://stable.melpa.org/packages/") ;; Some packages might only do stable releases? 15 | )) 16 | 17 | (package-initialize) 18 | 19 | ;; Ensure use-package is present. From here on out, all packages are loaded 20 | ;; with use-package. Also, refresh the package archive on load so we can pull the latest packages. 21 | (unless (package-installed-p 'use-package) 22 | (package-refresh-contents) 23 | (package-install 'use-package)) 24 | 25 | (use-package exec-path-from-shell 26 | :config 27 | (exec-path-from-shell-initialize)) 28 | 29 | ;; Allow navigation between use-package stanzas with imenu. 30 | ;; This has to be set before loading use-package. 31 | (defvar use-package-enable-imenu-support t) 32 | (require 'use-package) 33 | (setq 34 | use-package-always-ensure t ;; Makes sure to download new packages if they aren't already downloaded 35 | use-package-verbose t) ;; Package install logging. Packages break, nice to know why. 36 | 37 | ;; Any Customize-based settings should live in custom.el, not here. 38 | (setq custom-file "~/.emacs.d/custom.el") 39 | (load custom-file 'noerror) 40 | 41 | ;;(use-package doom-themes 42 | ;; :init 43 | ;; (load-theme 'doom-one)) 44 | 45 | 46 | (use-package doom-themes 47 | :ensure t 48 | :config 49 | ;; Global settings (defaults) 50 | (setq doom-themes-enabqle-bold t ; if nil, bold is universally disabled 51 | doom-themes-enable-italic t) ; if nil, italics is universally disabled 52 | ;;(load-theme 'doom-one t) 53 | (load-theme 'doom-flatwhite t) 54 | ;; Enable flashing mode-line on errors 55 | (doom-themes-visual-bell-config) 56 | ;; Enable custom neotree theme (all-the-icons must be installed!) 57 | (doom-themes-neotree-config) 58 | ;; or for treemacs users 59 | (setq doom-themes-treemacs-theme "doom-atom") ; use "doom-colors" for less minimal icon theme 60 | (doom-themes-treemacs-config) 61 | ;; Corrects (and improves) org-mode's native fontification. 62 | (doom-themes-org-config)) 63 | 64 | 65 | 66 | 67 | ;;; OS specific config 68 | (defconst *is-a-mac* (eq system-type 'darwin)) 69 | (defconst *is-a-linux* (eq system-type 'gnu/linux)) 70 | 71 | ;; Emacs feels like it's developed with linux in mind, here are some mac UX improvements 72 | ;;(when *is-a-mac* 73 | ;; (setq mac-command-modifier 'meta) 74 | ;; (setq mac-option-modifier 'none) 75 | ;; (setq default-input-method "MacOSX")) 76 | 77 | ;; Some linux love, too 78 | ;;(when *is-a-linux* 79 | ;; (setq x-super-keysym 'meta)) 80 | 81 | ;; Fullscreen by default, as early as possible. This tiny window is not enough 82 | (add-to-list 'default-frame-alist '(fullscreen . maximized)) 83 | 84 | ;; Make M-x and other mini-buffers sortable, filterable 85 | (use-package ivy 86 | :init 87 | (ivy-mode 1) 88 | (global-set-key "\C-s" 'swiper) 89 | (unbind-key "S-SPC" ivy-minibuffer-map) 90 | (setq ivy-height 15 91 | ivy-use-virtual-buffers t 92 | ivy-use-selectable-prompt t)) 93 | 94 | (use-package ivy-bibtex) 95 | 96 | (use-package counsel 97 | :after ivy 98 | :init 99 | (counsel-mode 1) 100 | :bind (:map ivy-minibuffer-map)) 101 | 102 | ;; Company is the best Emacs completion system. 103 | (use-package company 104 | :bind (("C-." . company-complete)) 105 | :custom 106 | (company-idle-delay 0) ;; I always want completion, give it to me asap 107 | (company-dabbrev-downcase nil "Don't downcase returned candidates.") 108 | (company-show-numbers t "Numbers are helpful.") 109 | (company-tooltip-limit 10 "The more the merrier.") 110 | :config 111 | (global-company-mode) ;; We want completion everywhere 112 | 113 | ;; use numbers 0-9 to select company completion candidates 114 | (let ((map company-active-map)) 115 | (mapc (lambda (x) (define-key map (format "%d" x) 116 | `(lambda () (interactive) (company-complete-number ,x)))) 117 | (number-sequence 0 9)))) 118 | 119 | ;; source: https://stackoverflow.com/questions/19142142/auto-complete-mode-not-working 120 | (add-hook 'c++-mode-hook 121 | (lambda() 122 | (semantic-mode 1) 123 | (define-key c++-mode-map (kbd "C-z") 'c++-auto-complete))) 124 | 125 | (defun c++-auto-complete () 126 | (interactive) 127 | (let ((ac-sources 128 | `(ac-source-semantic 129 | ,@ac-sources))) 130 | (auto-complete))) 131 | 132 | 133 | 134 | 135 | 136 | ;; Flycheck is the newer version of flymake and is needed to make lsp-mode not freak out. 137 | (use-package flycheck 138 | :ensure t 139 | :init 140 | (global-flycheck-mode t) 141 | :config 142 | (add-hook 'prog-mode-hook 'flycheck-mode) ;; always lint my code 143 | (add-hook 'after-init-hook #'global-flycheck-mode)) 144 | (add-hook 'find-file-hooks 'turn-on-flyspell) ;; Turn on for all files. 145 | 146 | (autoload 'flycheck "flycheck" "" t) 147 | (flycheck-define-checker textlint 148 | "A linter for textlint." 149 | :command ("npx" "textlint" 150 | "--config" "/Users/blaine/.emacs.d/.textlintrc" 151 | "--format" "unix" 152 | "--rule" "write-good" 153 | "--rule" "no-start-duplicated-conjunction" 154 | "--rule" "max-comma" 155 | "--rule" "terminology" 156 | "--rule" "period-in-list-item" 157 | "--rule" "abbr-within-parentheses" 158 | "--rule" "alex" 159 | "--rule" "common-misspellings" 160 | "--rule" "en-max-word-count" 161 | "--rule" "diacritics" 162 | "--rule" "stop-words" 163 | "--plugin" 164 | (eval 165 | (if (derived-mode-p 'tex-mode) 166 | "latex" 167 | "@textlint/text")) 168 | source-inplace) 169 | :error-patterns 170 | ((warning line-start (file-name) ":" line ":" column ": " 171 | (message (one-or-more not-newline) 172 | (zero-or-more "\n" (any " ") (one-or-more not-newline))) 173 | line-end)) 174 | :modes (text-mode latex-mode org-mode markdown-mode) 175 | ) 176 | (add-to-list 'flycheck-checkers 'textlint) 177 | 178 | 179 | 180 | (use-package lsp-mode 181 | :init 182 | ;; set prefix for lsp-command-keymap (few alternatives - "C-l", "C-c l") 183 | (setq lsp-keymap-prefix "C-c l") 184 | :hook (;; replace XXX-mode with concrete major-mode(e. g. python-mode) 185 | (latex-mode . lsp) 186 | ;; if you want which-key integration 187 | (lsp-mode . lsp-enable-which-key-integration)) 188 | :commands lsp) 189 | 190 | ;; optionally 191 | ;; (use-package lsp-ui :commands lsp-ui-mode) 192 | ;; if you are helm user 193 | ;; (use-package helm-lsp :commands helm-lsp-workspace-symbol) 194 | ;; if you are ivy user 195 | (use-package lsp-ivy :commands lsp-ivy-workspace-symbol) 196 | (use-package lsp-treemacs :commands lsp-treemacs-errors-list) 197 | 198 | ;; optionally if you want to use debugger 199 | ;; (use-package dap-mode) 200 | ;; (use-package dap-LANGUAGE) to load the dap adapter for your language 201 | 202 | ;; optional if you want which-key integration 203 | ;; (use-package which-key 204 | ;; :config 205 | ;; (which-key-mode)) 206 | ;; 207 | ;; Old version 208 | ;; ;; Package for interacting with language servers 209 | ;; (use-package lsp-mode 210 | ;; :commands lsp 211 | ;; :hook 212 | ;; (sh-mode . lsp) 213 | ;; :config 214 | ;; (setq lsp-prefer-flymake nil ;; Flymake is outdated 215 | ;; lsp-headerline-breadcrumb-mode nil)) ;; I don't like the symbols on the header a-la-vscode, remove this if you like them. 216 | 217 | ;; Basic python configuration 218 | (use-package python 219 | :init 220 | (require 'python) 221 | :config 222 | ;; As soon as we detect python go look for that virtual env. 223 | (add-hook 'python-mode-hook #'auto-virtualenv-set-virtualenv)) 224 | 225 | ;; Pyenv is the only reasonable way to manage python installs. What a mess. 226 | (use-package pyvenv) 227 | 228 | ;; Auto detect my virtual env, please 229 | (use-package auto-virtualenv) 230 | 231 | ;; Use the microsoft-python language server, it's the best available as of writing this 232 | (use-package lsp-python-ms 233 | :hook (python-mode . (lambda () 234 | (require 'lsp-python-ms) 235 | (lsp)))) ; or lsp-deferred 236 | 237 | ;; We need something to manage the various projects we work on 238 | ;; and for common functionality like project-wide searching, fuzzy file finding etc. 239 | ;; Use C-x p f to add a file to a project. 240 | (use-package projectile 241 | :init 242 | (projectile-mode t) ;; Enable this immediately 243 | :config 244 | (define-key projectile-mode-map (kbd "C-x p") 'projectile-command-map) 245 | (setq projectile-enable-caching t ;; Much better performance on large projects 246 | projectile-completion-system 'ivy)) ;; Ideally the minibuffer should aways look similar 247 | 248 | ;; Counsel and projectile should work together. 249 | (use-package counsel-projectile 250 | :init 251 | (counsel-projectile-mode)) 252 | 253 | ;; This is the best git client ever. 254 | ;; I know some people who only use emacs for magit (i.e dev in IntelliJ and commit/rebase/diff in emacs) 255 | ;; it's that good. 256 | (use-package magit 257 | :config 258 | (magit-auto-revert-mode t) ;; Buffers will reload automatically if for example you hard-reset/revert changes in magit 259 | (setq magit-completing-read-function 'ivy-completing-read)) ;; Everything should work with Ivy 260 | 261 | ;; replace C-x o with M-o 262 | (global-set-key (kbd "M-o") 'other-window) 263 | 264 | ;; this setting lets you move between windows cardinally with shift-arrows 265 | (windmove-default-keybindings) 266 | 267 | ;;;; Begin improvements 268 | ;; 269 | ;;;; The best package for managing opened files that I've ever used. 270 | ;;;; No more tabbing through 10 open files, and no more counting your open files to Cmd-num to. 271 | ;;(use-package ace-window 272 | ;; :bind 273 | ;; ("M-o" . ace-window) 274 | ;; :config 275 | ;; (set-face-attribute 'aw-leading-char-face nil 276 | ;; :foreground "deep sky blue" 277 | ;; :weight 'bold 278 | ;; :height 2.0) ;; Some nice formatting to make the letters more visible 279 | ;; (setq aw-scope 'frame) 280 | ;; (setq aw-dispatch-always t) 281 | ;; (setq aw-keys '(?q ?w ?e ?r ?a ?s ?d ?f)) 282 | ;; (setq aw-dispatch-alist '((?c aw-swap-window "Ace - Swap Window") 283 | ;; (?n aw-flip-window))) 284 | ;; (ace-window-display-mode t)) 285 | 286 | ;; Sort M-x by recently used, I can't believe this isn't a default already. 287 | (use-package smex) 288 | 289 | ;; Begin evil config 290 | 291 | ;; Optional for vim users 292 | ;;(use-package evil 293 | ;; :init 294 | ;; (evil-mode t)) 295 | 296 | 297 | ;;;;;;;;;;;;;;;; My settings 298 | 299 | ;; https://github.com/purcell/exec-path-from-shell 300 | (when (memq window-system '(mac ns x)) 301 | (exec-path-from-shell-initialize)) 302 | 303 | 304 | ;; Common settings 305 | ;; Do not end sentences with more than one whitespace. 306 | (setq sentence-end-double-space nil) 307 | ;; Display line numbers 308 | (when (version<= "26.0.50" emacs-version) 309 | (global-display-line-numbers-mode)) 310 | 311 | ;; not GUI tool bar 312 | (tool-bar-mode 0) 313 | 314 | ;; display time on model line 315 | (display-time-mode t) 316 | 317 | ;; set PATHS 318 | (use-package exec-path-from-shell 319 | :init 320 | (setenv "SHELL" "/bin/zsh") 321 | :ensure t 322 | :if (memq window-system '(mac ns x)) 323 | :config 324 | (setq exec-path-from-shell-variables '("PATH" "GOPATH")) 325 | (exec-path-from-shell-initialize)) 326 | 327 | ;; https://github.com/manateelazycat/awesome-tab 328 | (use-package awesome-tab 329 | :load-path "~/Dropbox/softwareDropBox/elisp/awesome-tab" 330 | :config 331 | (awesome-tab-mode t)) 332 | 333 | 334 | ;; dashboard 335 | (use-package dashboard 336 | :ensure t 337 | :config 338 | (dashboard-setup-startup-hook)) 339 | 340 | (setq dashboard-center-content t) 341 | (setq dashboard-insert-ascii-banner-centered t) 342 | (setq dashboard-banner-logo-title "Loxo or selpercatinib. FDA approved inhibitor for lung caner in 2020.") 343 | (use-package all-the-icons) 344 | (insert (all-the-icons-icon-for-buffer)) 345 | (setq dashboard-center-content t) 346 | (setq dashboard-image-banner-max-width 222) 347 | (setq dashboard-image-banner-max-height 169) 348 | (use-package page-break-lines) 349 | (setq dashboard-set-heading-icons t) 350 | (setq dashboard-set-file-icons t) 351 | (setq dashboard-startup-banner "/Users/blaine/images/loxo.png") 352 | (setq dashboard-items '((recents . 12) 353 | (bookmarks . 25) 354 | (projects . 20) 355 | (agenda . 15) 356 | (registers . 5))) 357 | ;; Set the title 358 | ;;(setq dashboard-banner-logo-title "Dashboard of Blaine Mooers") 359 | ;; Set the banner 360 | ;;(setq dashboard-startup-banner 'official) 361 | ;;(setq dashboard-startup-banner "/Users/blaine/Images/jmjd4alphaFOld1Aug30.png") 362 | ;; Value can be 363 | ;; 'official which displays the official emacs logo 364 | ;; 'logo which displays an alternative emacs logo 365 | ;; 1, 2 or 3 which displays one of the text banners 366 | ;; "path/to/your/image.gif", "path/to/your/image.png" or "path/to/your/text.txt" which displays whatever gif/image/text you would prefer 367 | 368 | ;; Content is not centered by default. To center, set 369 | ;;(setq dashboard-center-content t) 370 | 371 | ;; To disable shortcut "jump" indicators for each section, set 372 | (setq dashboard-show-shortcuts nil) 373 | 374 | ; To show info about the packages loaded and the init time: 375 | (setq dashboard-set-init-info t) 376 | 377 | ; To use it with counsel-projectile or persp-projectile 378 | (setq dashboard-projects-switch-function 'projectile-persp-switch-project) 379 | 380 | ; To display today’s agenda items on the dashboard, add agenda to dashboard-items: 381 | (add-to-list 'dashboard-items '(agenda) t) 382 | 383 | ;To show agenda for the upcoming seven days set the variable dashboard-week-agenda to t. 384 | (setq dashboard-week-agenda t) 385 | 386 | 387 | 388 | 389 | ;; (load-theme 'leuven t) 390 | 391 | ;; (use-package tommyh-theme 392 | ;; :config 393 | ;; (load-theme 'tommyh t)) 394 | 395 | 396 | ;; use org mode 397 | (use-package org) 398 | 399 | ;; 400 | (define-key global-map "\C-ca" 'org-agenda) 401 | (setq org-log-done t) 402 | 403 | ;; org-capture 404 | (define-key global-map "\C-cc" 'org-capture) 405 | (global-set-key (kbd "") 'org-capture) 406 | (define-key global-map "\C-cl" 'org-store-link) 407 | ;; Total word count for a org file and word count by headline. 408 | (define-key global-map "\C-cw" 'org-wc-display) 409 | ;; Open a fileset in separate windows. 410 | (define-key global-map "\C-cfo" 'filesets-open) 411 | ;; Open a fileset in separate windows. 412 | (define-key global-map "\C-cfc" 'filesets-close) 413 | 414 | 415 | ;; ;; word count 416 | ;; (defun my-latex-setup () 417 | ;; defun latex-word-count () 418 | ;; (interactive) 419 | ;; (let* ((this-file (buffer-file-name)) 420 | ;; (word-count 421 | ;; (with-output-to-string 422 | ;; (with-current-buffer standard-output 423 | ;; (call-process "/usr/local/bin/texcount.pl" nil t nil "-brief" this-file))))) 424 | ;; (string-match "\n$" word-count) 425 | ;; (message (replace-match "" nil nil word-count)))) 426 | ;; (define-key LaTeX-mode-map "\C-cw" 'latex-word-count)) 427 | ;; (add-hook 'LaTeX-mode-hook 'my-latex-setup t) 428 | ;; 429 | ;; ;; Fold and unfold sectin with C-tab 430 | ;; (add-hook 'LaTeX-mode-hook 'outline-minor-mode) 431 | ;; ;;(define-key LaTeX-mode-map (kbd "") 'outline-toggle-children) 432 | 433 | 434 | ;; Using M and C keys to fold. https://www.emacswiki.org/emacs/OutlineMinorMode 435 | (global-set-key [M-left] 'outline-hide-body) 436 | (global-set-key [M-right] 'outline-show-subtree) 437 | (global-set-key [M-up] 'outline-previous-heading) 438 | (global-set-key [M-down] 'outline-next-heading) 439 | (global-set-key [C-M-left] 'outline-hide-sublevels) 440 | (global-set-key [C-M-right] 'outline-show-children) 441 | (global-set-key [C-M-up] 'outline-previous-visible-heading) 442 | (global-set-key [C-M-down] 'outline-next-visible-heading) 443 | 444 | 445 | 446 | 447 | (use-package dropbox) 448 | (use-package oauth) 449 | (use-package json) 450 | 451 | 452 | 453 | ;; ;; LaTeX grammar checker via language tool. 454 | ;; ;; https://github.com/emacs-languagetool/lsp-ltex 455 | ;; (use-package lsp-latex 456 | ;; ensure t 457 | ;; hook (text-mode . (lambda () 458 | ;; (require 'lsp-latex) 459 | ;; (lsp)))) ; or lsp-deferred 460 | 461 | (use-package writegood-mode) 462 | (global-set-key "\C-cg" 'writegood-mode) 463 | 464 | 465 | ;; emacs-grammarly 466 | ;; https://github.com/emacs-grammarly/send-to-osx-grammarly 467 | ;; grammarly.app and new file msut be open 468 | ;; load el file in your .emacs, e.g. 469 | ;;;; (load-file "~/.emacs.d/plugins/send-to-osx-grammarly/send-to-osx-grammarly.el") 470 | ;;;; (call-process-shell-command "osascript ~/.emacs.d/plugins/send-to-osx-grammarly/pull.scpt") 471 | ;;;; (define-key global-map (kbd "C-c C-g h") #'send-to-osx-grammarly-push) 472 | ;;;; (define-key global-map (kbd "C-c C-g l") #'send-to-osx-grammarly-pull) 473 | ;;;; ;; 474 | ;;;; (require 'keytar) 475 | ;;;; ;;(message "%s" (keytar-get-password "vscode-grammarly-cookie" "default")) 476 | ;;;; 477 | ;;;; ;; https://github.com/emacs-grammarly/lsp-grammarly 478 | ;;;; (use-package lsp-grammarly 479 | ;;;; :ensure t 480 | ;;;; :hook (text-mode . (lambda () 481 | ;;;; (require 'lsp-grammarly) 482 | ;;;; (lsp)))) ; or lsp-deferred 483 | ;;;; (setq lsp-grammarly-auto-activate t) 484 | ;;;; 485 | ;;;; (require 'grammarly) 486 | ;;;; 487 | ;;;; (defun test-on-message (data) 488 | ;;;; "On message callback with DATA." 489 | ;;;; (message "[DATA] %s" data)) 490 | ;;;; 491 | ;;;; ;; Set callback for receiving data. 492 | ;;;; (add-to-list 'grammarly-on-message-function-list 'test-on-message) 493 | ;;;; 494 | ;;;; ;; Send check text request. 495 | ;;;; (grammarly-check-text "Hello World") 496 | ;;;; 497 | ;;;; (setq grammarly-username "bmooers1@gmail.com") ; Your Grammarly Username 498 | ;;;; (setq grammarly-password "**********") ; Your Grammarly Password 499 | 500 | ;; https://github.com/emacs-grammarly 501 | ;(require 'flycheck-grammarly) 502 | ;(add-hook 'text-mode-hook 'flymake-grammarly-load) 503 | ;(add-hook 'latex-mode-hook 'flymake-grammarly-load) 504 | ;(add-hook 'org-mode-hook 'flymake-grammarly-load) 505 | ;(add-hook 'markdown-mode-hook 'flymake-grammarly-load) 506 | 507 | (use-package keytar) 508 | 509 | ;; Source https://bpa.st/ST3Q 510 | ;; ;; Show and hide blocks in 511 | ;; (defun my/org-show-blocks (arg) 512 | ;; "Show all blocks in the current subtree. 513 | ;; 514 | ;; With prefix argument, show all blocks in the current buffer." 515 | ;; (interactive "p") 516 | ;; (if (eq arg 4) 517 | ;; (org-show-all '(blocks)) 518 | ;; (save-restriction 519 | ;; (org-narrow-to-subtree) 520 | ;; (org-show-all '(blocks))))) 521 | ;; 522 | ;; (define-key org-mode-map (kbd "C-c s b") 'my/org-show-blocks) 523 | ;; 524 | ;; (defun my/org-hide-blocks (arg) 525 | ;; "Fold all blocks in the current subtree. 526 | ;; 527 | ;; With prefix argument, fold all blocks in the current buffer." 528 | ;; (interactive "p") 529 | ;; (if (eq arg 4) 530 | ;; (org-hide-block-all) 531 | ;; (save-restriction 532 | ;; (org-narrow-to-subtree) 533 | ;; (org-hide-block-all)))) 534 | ;; 535 | ;; (define-key org-mode-map (kbd "C-c h b") 'my/org-hide-blocks) 536 | 537 | ;; 538 | ;; ;; org-bullets 539 | ;; (use-package org-bullets 540 | ;; after org 541 | ;; hook (org-mode . org-bullets-mode) 542 | ;; custom 543 | ;; org-bullets-bullet-list '("◉" "○" "●" "○" "●" "○" "●"))) 544 | ;; 545 | ;; https://github.com/sabof/org-bullets 546 | (require 'org-bullets) 547 | (add-hook 'org-mode-hook (lambda () (org-bullets-mode 1))) 548 | 549 | 550 | ;; org-journal 551 | (use-package org-journal) 552 | (setq org-journal-dir="~/gtd/journal") 553 | 554 | ;; org-latex minted 555 | 556 | (add-to-list 'org-latex-packages-alist '("" "minted")) 557 | (setq org-latex-listings 'minted) 558 | 559 | (setq org-latex-minted-options 560 | '(("frame" "lines") ("linenos=false") ("framerule=2pt") ("breaklines"))) 561 | (setq org-latex-pdf-process 562 | '("pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f" 563 | "pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f" 564 | "pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f")) 565 | (setq org-src-fontify-natively t) 566 | 567 | 568 | 569 | ;; org pomodoro 570 | (use-package org-pomodoro 571 | :ensure t 572 | :commands (org-pomodoro) 573 | :config 574 | (setq alert-user-configuration (quote ((((:category . "org-pomodoro")) libnotify nil))))) 575 | 576 | (use-package sound-wav) 577 | (setq org-pomodoro-ticking-sound-p 1) 578 | ; (setq org-pomodoro-ticking-sound-states '(:pomodoro :short-break :long-break)) 579 | (setq org-pomodoro-ticking-sound-states '(:pomodoro)) 580 | (setq org-pomodoro-ticking-frequency 1) 581 | (setq org-pomodoro-audio-player "mplayer") 582 | (setq org-pomodoro-finished-sound-args "-volume 0.9") 583 | (setq org-pomodoro-long-break-sound-args "-volume 0.9") 584 | (setq org-pomodoro-short-break-sound-args "-volume 0.9") 585 | (setq org-pomodoro-ticking-sound-args "-volume 0.3") 586 | 587 | (global-set-key (kbd "C-c o") 'org-pomodoro) 588 | 589 | ;; org-ref 590 | (use-package org-ref) 591 | 592 | (setq bibtex-completion-bibliography '("~/Dropbox/global.bib") 593 | bibtex-completion-library-path '("/Users/blaine/Dropbox/RNAdrugComplexCrystallizationPDFs/") 594 | bibtex-completion-notes-path "~/bibliography/notes/" 595 | bibtex-completion-notes-template-multiple-files "* ${author-or-editor}, ${title}, ${journal}, (${year}) :${=type=}: \n\nSee [[cite:&${=key=}]]\n" 596 | 597 | bibtex-completion-additional-search-fields '(keywords) 598 | bibtex-completion-display-formats 599 | '((article . "${=has-pdf=:1}${=has-note=:1} ${year:4} ${author:36} ${title:*} ${journal:40}") 600 | (inbook . "${=has-pdf=:1}${=has-note=:1} ${year:4} ${author:36} ${title:*} Chapter ${chapter:32}") 601 | (incollection . "${=has-pdf=:1}${=has-note=:1} ${year:4} ${author:36} ${title:*} ${booktitle:40}") 602 | (inproceedings . "${=has-pdf=:1}${=has-note=:1} ${year:4} ${author:36} ${title:*} ${booktitle:40}") 603 | (t . "${=has-pdf=:1}${=has-note=:1} ${year:4} ${author:36} ${title:*}")) 604 | bibtex-completion-pdf-open-function 605 | (lambda (fpath) 606 | (call-process "open" nil 0 nil fpath))) 607 | 608 | (use-package bibtex) 609 | 610 | (setq bibtex-autokey-year-length 4 611 | bibtex-autokey-name-year-separator "-" 612 | bibtex-autokey-year-title-separator "-" 613 | bibtex-autokey-titleword-separator "-" 614 | bibtex-autokey-titlewords 2 615 | bibtex-autokey-titlewords-stretch 1 616 | bibtex-autokey-titleword-length 5 617 | org-ref-bibtex-hydra-key-binding (kbd "H-b")) 618 | 619 | (define-key bibtex-mode-map (kbd "H-b") 'org-ref-bibtex-hydra/body) 620 | 621 | ;;(use-package org-ref-ivy) 622 | 623 | (define-key org-mode-map (kbd "C-c ]") 'org-ref-insert-link) 624 | 625 | 626 | (use-package gnuplot-mode) 627 | ;; (require 'org-babel) 628 | ;; (require 'org-babel-init) 629 | ;;(require 'org-babel-gnuplot) 630 | 631 | 632 | (org-babel-do-load-languages 633 | 'org-babel-load-languages 634 | '((emacs-lisp . nil) 635 | (C . t) 636 | (js . t) 637 | (ditaa . t) 638 | (ipython . t) 639 | (python . t) 640 | (gnuplot . t) 641 | (R . t) 642 | (latex . t) 643 | (plantuml . t) 644 | (shell . t) 645 | (jupyter . t) ) ) 646 | 647 | ;; enable use of python instead of python-juptyer 648 | (org-babel-jupyter-override-src-block "python") 649 | 650 | 651 | 652 | ;; yansippets 653 | (use-package yasnippet 654 | :init 655 | (add-to-list 'load-path 656 | "~/.emacs.d/plugins/yasnippet") 657 | ;; Directory listed below first is the personal snippets directory. 658 | ;; Early directories override later ones when there are name conflicts. 659 | ;; Snippets from all directories are pooled. 660 | :config 661 | (setq yas-snippet-dirs 662 | '("~/.emacs.d/snippets" ;; personal snippets. 663 | "/Users/blaine/Dropbox/softwareDropBox/yasmate/snippets" ;; the yasmate collection 664 | "~/.emacs.d/elpa/yasnippet-snippets-20210910.1959/snippets" ;; yasnippets-snippets 665 | )) 666 | (yas-global-mode 1)) 667 | 668 | 669 | ;; Enable tab triggers to work in native code language of the code block. 670 | (setq org-src-tab-acts-natively t 671 | org-confirm-babel-evaluate nil 672 | org-edit-src-content-indentation 0) 673 | 674 | ;; Turn off org-mode snippets inside org-blocks 675 | (defun my-org-mode-hook () 676 | (setq-local yas-buffer-local-condition 677 | '(not (org-in-src-block-p t)))) 678 | 679 | ;; 'my-org-mode-hook 680 | (add-hook 'org-mode-hook `my-org-mode-hook) 681 | 682 | 683 | ;; See the scale of the preview of the LaTeX equation so you can see it. 684 | ;; Place point in equation and enter C-c C-x C-l to render. 685 | (setq org-format-latex-options (plist-put org-format-latex-options :scale 4.0)) 686 | 687 | ;; Open on startup 688 | ;; (find-file "~/gtd/journal/weight.org") 689 | 690 | ;; spelling 691 | (setq ispell-program-name "/opt/local/bin/aspell") 692 | 693 | 694 | (flycheck-define-checker proselint 695 | "A linter for prose." 696 | :command ("proselint" source-inplace) 697 | :error-patterns 698 | ((warning line-start (file-name) ":" line ":" column ": " 699 | (id (one-or-more (not (any " ")))) 700 | (message) line-end)) 701 | :modes (latex-mode text-mode markdown-mode gfm-mode)) 702 | 703 | (add-to-list 'flycheck-checkers 'proselint) 704 | 705 | 706 | (autoload 'flycheck "flycheck" "" t) 707 | (flycheck-define-checker textlint 708 | "A linter for textlint." 709 | :command ("npx" "textlint" 710 | "--config" "/Users/blaine/.emacs.d/.textlintrc" 711 | "--format" "unix" 712 | "--rule" "write-good" 713 | "--rule" "no-start-duplicated-conjunction" 714 | "--rule" "max-comma" 715 | "--rule" "terminology" 716 | "--rule" "period-in-list-item" 717 | "--rule" "abbr-within-parentheses" 718 | "--rule" "alex" 719 | "--rule" "common-misspellings" 720 | "--rule" "en-max-word-count" 721 | "--rule" "diacritics" 722 | "--rule" "stop-words" 723 | "--plugin" 724 | (eval 725 | (if (derived-mode-p 'tex-mode) 726 | "latex" 727 | "@textlint/text")) 728 | source-inplace) 729 | :error-patterns 730 | ((warning line-start (file-name) ":" line ":" column ": " 731 | (message (one-or-more not-newline) 732 | (zero-or-more "\n" (any " ") (one-or-more not-newline))) 733 | line-end)) 734 | :modes (text-mode latex-mode org-mode markdown-mode) 735 | ) 736 | (add-to-list 'flycheck-checkers 'textlint) 737 | 738 | 739 | ;; org-roam 740 | (use-package org-roam 741 | :ensure t 742 | :init 743 | (setq org-roam-v2-ack t) 744 | :custom 745 | (setq org-roam-directory "~/org-roam") 746 | (org-roam-completion-everywhere t) 747 | :bind (("C-c n l" . org-roam-buffer-toggle) 748 | ("C-c n f" . org-roam-node-find) 749 | ("C-c n i" . org-roam-node-insert) 750 | () 751 | :map org-mode-map 752 | ("C-M-i" . completion-at-point)) 753 | :config 754 | (org-roam-setup)) 755 | 756 | (add-to-list 'load-path "~/.emacs.d/private/org-roam-ui") 757 | (load-library "org-roam-ui") 758 | 759 | 760 | ;; moving lines in org 761 | (defun move-line (n) 762 | "Move the current line up or down by N lines." 763 | (interactive "p") 764 | (setq col (current-column)) 765 | (beginning-of-line) (setq start (point)) 766 | (end-of-line) (forward-char) (setq end (point)) 767 | (let ((line-text (delete-and-extract-region start end))) 768 | (forward-line n) 769 | (insert line-text) 770 | ;; restore point to original column in moved line 771 | (forward-line -1) 772 | (forward-char col))) 773 | 774 | (defun move-line-up (n) 775 | "Move the current line up by N lines." 776 | (interactive "p") 777 | (move-line (if (null n) -1 (- n)))) 778 | 779 | (defun move-line-down (n) 780 | "Move the current line down by N lines." 781 | (interactive "p") 782 | (move-line (if (null n) 1 n))) 783 | 784 | (global-set-key (kbd "M-") 'move-line-up) 785 | (global-set-key (kbd "M-") 'move-line-down) 786 | 787 | 788 | ;; ;; word counting in subtree 789 | ;; (defun my/count-words-in-subtree-or-region () 790 | ;; ;; Bind this to a key in org-mode, e.g. C-= 791 | ;; (interactive) 792 | ;; (call-interactively (if (region-active-p) 793 | ;; 'count-words-region 794 | ;; 'my/count-words-in-subtree))) 795 | ;; 796 | ;; (defun my/count-words-in-subtree () 797 | ;; "Count words in current node and child nodes, excluding heading text." 798 | ;; (interactive) 799 | ;; (org-with-wide-buffer 800 | ;; (message "%s words in subtree" 801 | ;; (-sum (org-map-entries 802 | ;; (lambda () 803 | ;; (outline-back-to-heading) 804 | ;; (forward-line 1) 805 | ;; (while (or (looking-at org-keyword-time-regexp) 806 | ;; (org-in-drawer-p)) 807 | ;; (forward-line 1)) 808 | ;; (count-words (point) 809 | ;; (progn 810 | ;; (outline-end-of-subtree) 811 | ;; (point)))) 812 | ;; nil 'tree))))) 813 | 814 | 815 | ;; ;; mode-line configuration for clojure 816 | ;; ;; http://jr0cket.co.uk/2013/01/tweeking-emacs-modeline-for-clojure.html.html 817 | ;; (defvar mode-line-cleaner-alist 818 | ;; `((auto-complete-mode . " α") 819 | ;; (yas-minor-mode . " γ") 820 | ;; (paredit-mode . " Φ") 821 | ;; (eldoc-mode . "") 822 | ;; (abbrev-mode . "") 823 | ;; (undo-tree-mode . " τ") 824 | ;; (volatile-highlights-mode . " υ") 825 | ;; (elisp-slime-nav-mode . " δ") 826 | ;; (nrepl-mode . " ηζ") 827 | ;; (nrepl-interaction-mode . " ηζ") 828 | ;; ;; Major modes 829 | ;; (clojure-mode . "λ") 830 | ;; (hi-lock-mode . "") 831 | ;; (python-mode . "Py") 832 | ;; (emacs-lisp-mode . "EL") 833 | ;; (markdown-mode . "md")) 834 | ;; 835 | ;; (defun clean-mode-line () 836 | ;; (interactive) 837 | ;; (loop for cleaner in mode-line-cleaner-alist 838 | ;; do (let* ((mode (car cleaner)) 839 | ;; (mode-str (cdr cleaner)) 840 | ;; (old-mode-str (cdr (assq mode minor-mode-alist)))) 841 | ;; (when old-mode-str 842 | ;; (setcar old-mode-str mode-str)) 843 | ;; ;; major mode 844 | ;; (when (eq mode major-mode) 845 | ;; (setq mode-name mode-str))))) 846 | ;; 847 | ;; (add-hook 'after-change-major-mode-hook 'clean-mode-line) 848 | ;; 849 | ;; 850 | ;; 851 | ;; ;; powerline 852 | ;; (use-package powerline 853 | ;; :ensure t 854 | ;; :config 855 | ;; (powerline-evil-vim-color-theme) 856 | ;; (setq powerline-arrow-shape 'arrow) ;; the default 857 | ;; (custom-set-faces 858 | ;; ;; custom-set-faces was added by Custom. 859 | ;; ;; If you edit it by hand, you could mess it up, so be careful. 860 | ;; ;; Your init file should contain only one such instance. 861 | ;; ;; If there is more than one, they won't work right. 862 | ;; '(mode-line ((t (:foreground "#030303" :background "#bdbdbd" :box nil)))) 863 | ;; '(mode-line-inactive ((t (:foreground "#f9f9f9" :background "#666666" :box nil))))) 864 | ;; ) 865 | ;; 866 | ;; 867 | ;; 868 | ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 869 | ;; ;; Web lookup 870 | ;; ;; Source: \url{http://ergoemacs.org/emacs/xah-lookup.html} 871 | ;; ;; The curlicue is the lookup word query string place-holder. 872 | ;; 873 | ;; (add-to-list 'load-path "~/.emacs.d/lisp/lookup-word-on-internet") 874 | ;; (use-package 'xah-lookup) 875 | ;; (define-key help-map (kbd "7") 'xah-lookup-web) ; C-h 7 876 | ;; (global-set-key (kbd "") 'xah-lookup-wikipedia) ; F2 877 | ;; 878 | ;; 879 | ;; 880 | ;; (defun my-lookup-cctbx (&optional @word) 881 | ;; "Lookup cctbx documentation of word under cursor." 882 | ;; (interactive) 883 | ;; (require 'xah-lookup) 884 | ;; (xah-lookup-word-on-internet 885 | ;; @word 886 | ;; (get 'my-lookup-cctbx 'xah-lookup-url ) 887 | ;; (get 'my-lookup-cctbx 'xah-lookup-browser-function ))) 888 | ;; 889 | ;; (put 'my-lookup-cctbx 'xah-lookup-url "https://cctbx.github.io/search.html?q=curlicue") 890 | ;; (put 'my-lookup-cctbx 'xah-lookup-browser-function 'browse-url) 891 | ;; 892 | ;; 893 | ;; (defun my-lookup-github (&optional @word) 894 | ;; "Lookup github documentation of word under cursor." 895 | ;; (interactive) 896 | ;; (require 'xah-lookup) 897 | ;; (xah-lookup-word-on-internet 898 | ;; @word 899 | ;; (get 'my-lookup-github 'xah-lookup-url ) 900 | ;; (get 'my-lookup-github 'xah-lookup-browser-function ))) 901 | ;; 902 | ;; (put 'my-lookup-github 'xah-lookup-url "https://github.com/search?q==curlicue") 903 | ;; (put 'my-lookup-github 'xah-lookup-browser-function 'browse-url) 904 | ;; 905 | ;; 906 | ;; (defun my-lookup-jstor (&optional @word) 907 | ;; "Lookup jstor documentation of word under cursor." 908 | ;; (interactive) 909 | ;; (require 'xah-lookup) 910 | ;; (xah-lookup-word-on-internet 911 | ;; @word 912 | ;; (get 'my-lookup-jstor 'xah-lookup-url ) 913 | ;; (get 'my-lookup-jstor 'xah-lookup-browser-function ))) 914 | ;; 915 | ;; (put 'my-lookup-jstor 'xah-lookup-url "https://www.jstor.org/action/doBasicSearch?Query=curlicue") 916 | ;; (put 'my-lookup-jstor 'xah-lookup-browser-function 'browse-url) 917 | ;; 918 | ;; 919 | ;; (defun my-lookup-julia (&optional @word) 920 | ;; "Lookup cctbx documentation of word under cursor." 921 | ;; (interactive) 922 | ;; (require 'xah-lookup) 923 | ;; (xah-lookup-word-on-internet 924 | ;; @word 925 | ;; (get 'my-lookup-julia 'xah-lookup-url ) 926 | ;; (get 'my-lookup-julia 'xah-lookup-browser-function ))) 927 | ;; 928 | ;; (put 'my-lookup-julia 'xah-lookup-url "https://docs.julialang.org/en/v1/search/?q=curlicue") 929 | ;; (put 'my-lookup-julia 'xah-lookup-browser-function 'browse-url) 930 | ;; 931 | ;; 932 | ;; (defun my-lookup-juliaobserver (&optional @word) 933 | ;; "Lookup cctbx documentation of word under cursor." 934 | ;; (interactive) 935 | ;; (require 'xah-lookup) 936 | ;; (xah-lookup-word-on-internet 937 | ;; @word 938 | ;; (get 'my-lookup-juliaobserver 'xah-lookup-url ) 939 | ;; (get 'my-lookup-juliaobserver 'xah-lookup-browser-function ))) 940 | ;; 941 | ;; (put 'my-lookup-juliaobserver 'xah-lookup-url "https://juliaobserver.com/searches?utf8=%E2%9C%93&term=curlicue") 942 | ;; (put 'my-lookup-juliaobserver 'xah-lookup-browser-function 'browse-url) 943 | ;; 944 | ;; 945 | ;; (defun my-lookup-connect (&optional @word) 946 | ;; "lookup connected papers of word under cursor" 947 | ;; (interactive) 948 | ;; (require 'xah-lookup) 949 | ;; (xah-lookup-word-on-internet 950 | ;; @word 951 | ;; (get 'my-lookup-connect 'xah-lookup-url ) 952 | ;; (get 'my-lookup-connect 'xah-lookup-browser-function ))) 953 | ;; 954 | ;; (put 'my-lookup-connect 'xah-lookup-url "https://www.connectedpapers.com/search?q=curlicue") 955 | ;; (put 'my-lookup-connect 'xah-lookup-browser-function 'browse-url) 956 | ;; 957 | ;; 958 | ;; (defun my-lookup-matplotlib (&optional @word) 959 | ;; "lookup connected papers of word under cursor" 960 | ;; (interactive) 961 | ;; (require 'xah-lookup) 962 | ;; (xah-lookup-word-on-internet 963 | ;; @word 964 | ;; (get 'my-lookup-matplotlib 'xah-lookup-url ) 965 | ;; (get 'my-lookup-matplotlib 'xah-lookup-browser-function ))) 966 | ;; 967 | ;; (put 'my-lookup-connect 'xah-lookup-url "https://matplotlib.org/stable/search.html?q=curlicue") 968 | ;; (put 'my-lookup-connect 'xah-lookup-browser-function 'browse-url) 969 | ;; 970 | ;; 971 | ;; 972 | ;; (defun my-lookup-php (&optional @word) 973 | ;; "lookup php doc of word under cursor" 974 | ;; (interactive) 975 | ;; (require 'xah-lookup) 976 | ;; (xah-lookup-word-on-internet 977 | ;; @word 978 | ;; (get 'my-lookup-php 'xah-lookup-url ) 979 | ;; (get 'my-lookup-php 'xah-lookup-browser-function ))) 980 | ;; 981 | ;; (put 'my-lookup-php 'xah-lookup-url "https://us.php.net/curlicue") 982 | ;; (put 'my-lookup-php 'xah-lookup-browser-function 'browse-url) 983 | ;; 984 | ;; 985 | ;; (defun my-lookup-pubmed (&optional @word) 986 | ;; "Lookup cctbx documentation of word under cursor." 987 | ;; (interactive) 988 | ;; (require 'xah-lookup) 989 | ;; (xah-lookup-word-on-internet 990 | ;; @word 991 | ;; (get 'my-lookup-pubmed 'xah-lookup-url ) 992 | ;; (get 'my-lookup-pubmed 'xah-lookup-browser-function ))) 993 | ;; 994 | ;; (put 'my-lookup-pubmed 'xah-lookup-url "https://pubmed.ncbi.nlm.nih.gov/?term=curlicue") 995 | ;; (put 'my-lookup-pubmed 'xah-lookup-browser-function 'browse-url) 996 | ;; 997 | ;; 998 | ;; (defun my-lookup-pymol (&optional @word) 999 | ;; "Lookup cctbx documentation of word under cursor." 1000 | ;; (interactive) 1001 | ;; (require 'xah-lookup) 1002 | ;; (xah-lookup-word-on-internet 1003 | ;; @word 1004 | ;; (get 'my-lookup-pymol 'xah-lookup-url ) 1005 | ;; (get 'my-lookup-pymol 'xah-lookup-browser-function ))) 1006 | ;; 1007 | ;; (put 'my-lookup-pymol 'xah-lookup-url "https://pymol.org/dokuwiki/doku.php?do=search&id=curlicue") 1008 | ;; (put 'my-lookup-pymol 'xah-lookup-browser-function 'browse-url) 1009 | ;; 1010 | ;; 1011 | ;; (defun my-lookup-python (&optional @word) 1012 | ;; "Lookup Python.org doc of word under cursor." 1013 | ;; (interactive) 1014 | ;; (require 'xah-lookup) 1015 | ;; (xah-lookup-word-on-internet 1016 | ;; @word 1017 | ;; (get 'my-lookup-python 'xah-lookup-url ) 1018 | ;; (get 'my-lookup-python 'xah-lookup-browser-function ))) 1019 | ;; 1020 | ;; (put 'my-lookup-python 'xah-lookup-url "https://www.python.org/search/?q=curlicue") 1021 | ;; (put 'my-lookup-python 'xah-lookup-browser-function 'browse-url) 1022 | ;; 1023 | ;; 1024 | ;; (defun my-lookup-r (&optional @word) 1025 | ;; "Lookup R documentation of word under cursor." 1026 | ;; (interactive) 1027 | ;; (require 'xah-lookup) 1028 | ;; (xah-lookup-word-on-internet 1029 | ;; @word 1030 | ;; (get 'my-lookup-r 'xah-lookup-url ) 1031 | ;; (get 'my-lookup-r 'xah-lookup-browser-function ))) 1032 | ;; 1033 | ;; (put 'my-lookup-r 'xah-lookup-url "https://www.rdocumentation.org/search?q=curlicue") 1034 | ;; (put 'my-lookup-r 'xah-lookup-browser-function 'browse-url) 1035 | ;; 1036 | ;; 1037 | ;; (defun my-lookup-scholar (&optional @word) 1038 | ;; "Lookup Goolge Scholar doc of word under cursor" 1039 | ;; (interactive) 1040 | ;; (require 'xah-lookup) 1041 | ;; (xah-lookup-word-on-internet 1042 | ;; @word 1043 | ;; (get 'my-lookup-scholar 'xah-lookup-url ) 1044 | ;; (get 'my-lookup-scholar 'xah-lookup-browser-function ))) 1045 | ;; 1046 | ;; (put 'my-lookup-scholar 'xah-lookup-url "https://scholar.google.com/scholar?hl=en&as_sdt=0%2C37&q=curlicue") 1047 | ;; (put 'my-lookup-scholar 'xah-lookup-browser-function 'browse-url) 1048 | ;; 1049 | ;; 1050 | ;; (defun my-lookup-wikipedia (&optional @word) 1051 | ;; "Lookup wikipedia doc of word under cursor." 1052 | ;; (interactive) 1053 | ;; (require 'xah-lookup) 1054 | ;; (xah-lookup-word-on-internet 1055 | ;; @word 1056 | ;; (get 'my-lookup-wikipedia 'xah-lookup-url ) 1057 | ;; (get 'my-lookup-wikipedia 'xah-lookup-browser-function ))) 1058 | ;; 1059 | ;; (put 'my-lookup-wikipedia 'xah-lookup-url "https://en.wikipedia.org/wiki/curlicue") 1060 | ;; (put 'my-lookup-wikipedia 'xah-lookup-browser-function 'browse-url) 1061 | ;; 1062 | ;; 1063 | ;; (defun my-lookup-wolframalpha (&optional @word) 1064 | ;; "Lookup wolframalpha doc of word under cursor." 1065 | ;; (interactive) 1066 | ;; (require 'xah-lookup) 1067 | ;; (xah-lookup-word-on-internet 1068 | ;; @word 1069 | ;; (get 'my-lookup-wolframalpha 'xah-lookup-url ) 1070 | ;; (get 'my-lookup-wolframalpha 'xah-lookup-browser-function ))) 1071 | ;; 1072 | ;; (put 'my-lookup-wolframalpha 'xah-lookup-url "https://www.wolframalpha.com/input/?i=curlicue") 1073 | ;; (put 'my-lookup-wolframalpha 'xah-lookup-browser-function 'browse-url) 1074 | ;; 1075 | ;; 1076 | ;; (defun my-lookup-pdbj (&optional @word) 1077 | ;; "Lookup wolframalpha doc of word under cursor." 1078 | ;; (interactive) 1079 | ;; (require 'xah-lookup) 1080 | ;; (xah-lookup-word-on-internet 1081 | ;; @word 1082 | ;; (get 'my-lookup-pdbj 'xah-lookup-url ) 1083 | ;; (get 'my-lookup-pdbj 'xah-lookup-browser-function ))) 1084 | ;; 1085 | ;; (put 'my-lookup-pdbj 'xah-lookup-url "https://pdbj.org/search/pdb?query=curlicue") 1086 | ;; (put 'my-lookup-pdbj 'xah-lookup-browser-function 'browse-url) 1087 | ;; 1088 | ;; 1089 | ;; (defun my-lookup-pdbj (&optional @word) 1090 | ;; "Lookup wolframalpha doc of word under cursor." 1091 | ;; (interactive) 1092 | ;; (require 'xah-lookup) 1093 | ;; (xah-lookup-word-on-internet 1094 | ;; @word 1095 | ;; (get 'my-lookup-tensorfolw 'xah-lookup-url ) 1096 | ;; (get 'my-lookup-tensorfolw 'xah-lookup-browser-function ))) 1097 | ;; 1098 | ;; (put 'my-lookup-tensorfolw 'xah-lookup-url "https://www.tensorflow.org/s/results/?q=curlicue") 1099 | ;; (put 'my-lookup-tensorfolw 'xah-lookup-browser-function 'browse-url) 1100 | ;; 1101 | ;; 1102 | ;; (define-key help-map (kbd "\C-g") 'my-lookup-github) ; C-h C-g 1103 | ;; (define-key help-map (kbd "\C-j") 'my-lookup-julia) ; C-h C-j 1104 | ;; (define-key help-map (kbd "\C-m") 'my-lookup-pymol) ; C-h C-m 1105 | ;; (define-key help-map (kbd "\C-o") 'my-lookup-juliaobserver) ; C-h C-o 1106 | ;; (define-key help-map (kbd "\C-b") 'my-lookup-pubmed) ; C-h C-b 1107 | ;; (define-key help-map (kbd "\C-t") 'my-lookup-jstor) ; C-h C-t 1108 | ;; (define-key help-map (kbd "\C-c") 'my-lookup-connect) ; C-h C-c 1109 | ;; (define-key help-map (kbd "\C-l") 'my-lookup-matplotlib) ; C-h C-l 1110 | ;; (define-key help-map (kbd "\C-p") 'my-lookup-python) ; C-h C-p 1111 | ;; (define-key help-map (kbd "\C-r") 'my-lookup-r) ; C-h C_r 1112 | ;; (define-key help-map (kbd "\C-s") 'my-lookup-scholar) ; C-h C- s 1113 | ;; (define-key help-map (kbd "\C-w") 'my-lookup-wikipedia) ; C-h C-w 1114 | ;; (define-key help-map (kbd "\C-a") 'my-lookup-wolframalpha) ; C-h C-a 1115 | ;; (define-key help-map (kbd "\C-x") 'my-lookup-cctbx) ; C-h C-x 1116 | ;; (define-key help-map (kbd "\C-f") 'my-lookup-tensorfolw) ; C-h C-f 1117 | ;; (define-key help-map (kbd "\C-d") 'my-lookup-pdbj) ; C-h C-f 1118 | ;; (put 'narrow-to-region 'disabled nil) 1119 | ;; 1120 | ;; ;;; The SBCL binary and command-line arguments 1121 | ;; (setq inferior-lisp-program "/Users/blaine/.roswell/impls/x86-64/darwin/sbcl/2.1.9/bin/sbcl --noinform") 1122 | ;; (load (expand-file-name "~/.local/opt/quicklisp/slime-helper.el")) 1123 | ;; 1124 | ;; 1125 | ;; ;; new-dashboard 1126 | ;; ;; Function to refresh dashboard and open in current window. 1127 | ;; ;; This is useful for accessing bookmarks and recent files created in the current session 1128 | ;; ;; Source fo function: the issues section of the dashboard GitHub page. 1129 | ;; ;; Function by Jackson Benete Ferreira. 1130 | ;; ;; https://github.com/emacs-dashboard/emacs-dashboard/issues/236 1131 | ;; ;; I edited the documentation line to fix the grammar and add the final phrase. 1132 | ;; ;; Remap Open Dashboard 1133 | ;; (defun new-dashboard () 1134 | ;; "Jump to the dashboard buffer. If it doesn't exists, create one. Refresh while at it." 1135 | ;; (interactive) 1136 | ;; (switch-to-buffer dashboard-buffer-name) 1137 | ;; (dashboard-mode) 1138 | ;; (dashboard-insert-startupify-lists) 1139 | ;; (dashboard-refresh-buffer)) 1140 | ;; (global-set-key (kbd "") 'new-dashboard) 1141 | ;; 1142 | ;; 1143 | ;; ;; ------------------------------------ preview latex equations ------------------------------------ ;; 1144 | ;; ;; 1145 | ;; ;; 28.07.2017 1146 | ;; ;; Charles Wang 1147 | ;; ;; 1148 | ;; 1149 | ;;;;;;; Tweaks for Org & org-latex ;;;;;; 1150 | 1151 | ;; (defvar cw/org-last-fragment nil 1152 | ;; "Holds the type and position of last valid fragment we were on. Format: (FRAGMENT_TYPE FRAGMENT_POINT_BEGIN)" 1153 | ;; ) 1154 | ;; 1155 | ;; (setq cw/org-valid-fragment-type 1156 | ;; '(latex-fragment 1157 | ;; latex-environment 1158 | ;; link)) 1159 | ;; 1160 | ;; (defun cw/org-curr-fragment () 1161 | ;; "Returns the type and position of the current fragment available for preview inside org-mode. Returns nil at non-displayable fragments" 1162 | ;; (let* ((fr (org-element-context)) 1163 | ;; (fr-type (car fr))) 1164 | ;; (when (memq fr-type cw/org-valid-fragment-type) 1165 | ;; (list fr-type 1166 | ;; (org-element-property :begin fr)))) 1167 | ;; ) 1168 | ;; 1169 | ;; (defun cw/org-remove-fragment-overlay (fr) 1170 | ;; "Remove fragment overlay at fr" 1171 | ;; (let ((fr-type (nth 0 fr)) 1172 | ;; (fr-begin (nth 1 fr))) 1173 | ;; (goto-char fr-begin) 1174 | ;; (cond ((or (eq 'latex-fragment fr-type) 1175 | ;; (eq 'latex-environment fr-type)) 1176 | ;; (let ((ov (loop for ov in (org--list-latex-overlays) 1177 | ;; if 1178 | ;; (and 1179 | ;; (<= (overlay-start ov) (point)) 1180 | ;; (>= (overlay-end ov) (point))) 1181 | ;; return ov))) 1182 | ;; (when ov 1183 | ;; (delete-overlay ov)))) 1184 | ;; ((eq 'link fr-type) 1185 | ;; nil;; delete image overlay here? 1186 | ;; )) 1187 | ;; )) 1188 | ;; 1189 | ;; (defun cw/org-preview-fragment (fr) 1190 | ;; "Preview org fragment at fr" 1191 | ;; (let ((fr-type (nth 0 fr)) 1192 | ;; (fr-begin (nth 1 fr))) 1193 | ;; (goto-char fr-begin) 1194 | ;; (cond ((or (eq 'latex-fragment fr-type) ;; latex stuffs 1195 | ;; (eq 'latex-environment fr-type)) 1196 | ;; (when (cw/org-curr-fragment) (org-preview-latex-fragment))) ;; only toggle preview when we're in a valid region (for inserting in the front of a fragment) 1197 | ;; 1198 | ;; 1199 | ;; ((eq 'link fr-type) ;; for images 1200 | ;; (let ((fr-end (org-element-property :end (org-element-context)))) 1201 | ;; (org-display-inline-images nil t fr-begin fr-end)))) 1202 | ;; )) 1203 | ;; 1204 | ;; 1205 | ;; 1206 | ;; (defun cw/org-auto-toggle-fragment-display () 1207 | ;; "Automatically toggle a displayable org mode fragment" 1208 | ;; (and (eq 'org-mode major-mode) 1209 | ;; (let ((curr (cw/org-curr-fragment))) 1210 | ;; (cond 1211 | ;; ;; were on a fragment and now on a new fragment 1212 | ;; ((and 1213 | ;; ;; fragment we were on 1214 | ;; cw/org-last-fragment 1215 | ;; ;; and are on a fragment now 1216 | ;; curr 1217 | ;; ;; but not on the last one this is a little tricky. as you edit the 1218 | ;; ;; fragment, it is not equal to the last one. We use the begin 1219 | ;; ;; property which is less likely to change for the comparison. 1220 | ;; (not (equal curr cw/org-last-fragment))) 1221 | ;; 1222 | ;; ;; go back to last one and put image back, provided there is still a fragment there 1223 | ;; (save-excursion 1224 | ;; (cw/org-preview-fragment cw/org-last-fragment) 1225 | ;; ;; now remove current image 1226 | ;; (cw/org-remove-fragment-overlay curr) 1227 | ;; ;; and save new fragment 1228 | ;; ) 1229 | ;; (setq cw/org-last-fragment curr)) 1230 | ;; 1231 | ;; ;; were on a fragment and now are not on a fragment 1232 | ;; ((and 1233 | ;; ;; not on a fragment now 1234 | ;; (not curr) 1235 | ;; ;; but we were on one 1236 | ;; cw/org-last-fragment) 1237 | ;; ;; put image back on, provided that there is still a fragment here. 1238 | ;; (save-excursion 1239 | ;; (cw/org-preview-fragment cw/org-last-fragment)) 1240 | ;; 1241 | ;; ;; unset last fragment 1242 | ;; (setq cw/org-last-fragment nil)) 1243 | ;; 1244 | ;; ;; were not on a fragment, and now are 1245 | ;; ((and 1246 | ;; ;; we were not one one 1247 | ;; (not cw/org-last-fragment) 1248 | ;; ;; but now we are 1249 | ;; curr) 1250 | ;; ;; remove image 1251 | ;; (save-excursion 1252 | ;; (cw/org-remove-fragment-overlay curr) 1253 | ;; ) 1254 | ;; (setq cw/org-last-fragment curr)) 1255 | ;; 1256 | ;; )))) 1257 | ;; 1258 | ;; ;; Suppose to negate need to toggle 1259 | ;; (add hook 'post-command-hook 'cw/org-auto-toggle-fragment-display t) 1260 | ;; 1261 | 1262 | ;; Cider is an interactive env for Clojure 1263 | (use-package cider 1264 | :ensure t) 1265 | 1266 | ;; ;; turn pages of clojure cookbook with M-+ 1267 | ;; (defun increment-clojure-cookbook () 1268 | ;; "When reading the Clojure cookbook, find the next section, and 1269 | ;; close the buffer. If the next section is a sub-directory or in 1270 | ;; the next chapter, open Dired so you can find it manually." 1271 | ;; (interactive) 1272 | ;; (let* ((cur (buffer-name)) 1273 | ;; (split-cur (split-string cur "[-_]")) 1274 | ;; (chap (car split-cur)) 1275 | ;; (rec (car (cdr split-cur))) 1276 | ;; (rec-num (string-to-number rec)) 1277 | ;; (next-rec-num (1+ rec-num)) 1278 | ;; (next-rec-s (number-to-string next-rec-num)) 1279 | ;; (next-rec (if (< next-rec-num 10) 1280 | ;; (concat "0" next-rec-s) 1281 | ;; next-rec-s)) 1282 | ;; (target (file-name-completion (concat chap "-" next-rec) ""))) 1283 | ;; (progn 1284 | ;; (if (equal target nil) 1285 | ;; (dired (file-name-directory (buffer-file-name))) 1286 | ;; (find-file target)) 1287 | ;; (kill-buffer cur)))) 1288 | ;; 1289 | ;; (define-key adoc-mode-map (kbd "M-+") 'increment-clojure-cookbook) 1290 | ;; 1291 | ;; (add-hook 'adoc-mode-hook 'cider-mode) 1292 | ;; 1293 | ;; 1294 | ;; ;; Use the clojure-lsp 1295 | ;; (use-package lsp-mode 1296 | ;; :ensure t 1297 | ;; :hook ((clojure-mode . lsp) 1298 | ;; (clojurec-mode . lsp) 1299 | ;; (clojurescript-mode . lsp)) 1300 | ;; :config 1301 | ;; ;; add paths to your local installation of project mgmt tools, like lein 1302 | ;; (setenv "PATH" (concat 1303 | ;; "/usr/local/bin" path-separator 1304 | ;; (getenv "PATH"))) 1305 | ;; (dolist (m '(clojure-mode 1306 | ;; clojurec-mode 1307 | ;; clojurescript-mode 1308 | ;; clojurex-mode)) 1309 | ;; (add-to-list 'lsp-language-id-configuration `(,m . "clojure"))) 1310 | ;; (setq lsp-clojure-server-command '("/usr/local/Cellar/clojure-lsp-native"))) ;; Optional: In case `clojure-lsp` is not in your $PATH 1311 | ;; 1312 | ;; --------------------------------------------------------------------------------