━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ALEC'S A LANGUAGE FOR EXPRESSING CREATIVITY (ALEC) Grant Rettke ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ <2014-02-24 MON> Table of Contents ───────────────── 1 Start Up 2 Run-time 3 Provisioning .. 3.1 Background .. 3.2 Steps ..... 3.2.1 Package ..... 3.2.2 el-get 4 Ends & Means 5 Ends (ALEC) .. 5.1 The desire .. 5.2 The story .. 5.3 Inspirations 6 Means .. 6.1 Functions & Constants .. 6.2 Color Theme .. 6.3 Windows .. 6.4 Environment .. 6.5 Code folding .. 6.6 Buffers .. 6.7 Frames .. 6.8 File-system management (GUI) .. 6.9 File-system/directory management (Console) .. 6.10 Save history of all things .. 6.11 Spell-checking .. 6.12 Syntax checking .. 6.13 Templating .. 6.14 White-space management .. 6.15 Mark and Region .. 6.16 Modeline .. 6.17 Speed .. 6.18 Minibuffer .. 6.19 Searching / Finding / Replacing [89] [90] ..... 6.19.1 Searching ..... 6.19.2 Finding ..... 6.19.3 Replacing .. 6.20 Sudo .. 6.21 Popups .. 6.22 Intellisense (Auto Completion) [95] .. 6.23 Symbolic Expression Management [98] .. 6.24 Evaluation .. 6.25 Version control / Git .. 6.26 Command execution helper [105] .. 6.27 Rectangle / Cursors [107] [108] .. 6.28 Font .. 6.29 Project management [114] .. 6.30 Emacs Speaks Statistics (ESS) [115] [116] [117] [118] [119] [120] .. 6.31 Org ..... 6.31.1 Discussion ..... 6.31.2 Configuration .. 6.32 Keyboard 7 Keybindings .. 7.1 NON-DISRUPTIVE .. 7.2 SLIGHTLY-DISRUPTIVE .. 7.3 VERY DISRUPTIVE 8 Modes .. 8.1 C Language Integrated Production System (CLIPS) [167] .. 8.2 Comint .. 8.3 CSS .. 8.4 Emacs Lisp .. 8.5 Eshell [174] [175] [176] .. 8.6 Files .. 8.7 Graphviz [177] [178] [179] .. 8.8 Grammar .. 8.9 Help .. 8.10 ibuffer .. 8.11 IELM [187] [188] [189] .. 8.12 Imenu [191] [192] .. 8.13 Info [196] .. 8.14 Javascript [200] [201] .. 8.15 LilyPond [202] .. 8.16 Lispy .. 8.17 Make [204] [205] [206] .. 8.18 Markdown [207] .. 8.19 Occur .. 8.20 Pandoc [209] .. 8.21 Polymode [212] .. 8.22 Ruby [218] .. 8.23 Scheme [219] .. 8.24 Sh(hell) .. 8.25 Shell .. 8.26 Standard ML (SML) [222] .. 8.27 Strings .. 8.28 Structured Query Language (SQL) [225] .. 8.29 Table .. 8.30 TeX [228] / LaTeX [229] / ConTeXt [230] .. 8.31 Text .. 8.32 Vagrant [234] .. 8.33 Web [236] .. 8.34 Web browsing .. 8.35 TRAMP [240] .. 8.36 YAML .. 8.37 Diagramming, UML creation, Workflow ..... 8.37.1 Setup 9 Libraries .. 9.1 Generally nice .. 9.2 Built-in .. 9.3 Characters / Unicode 10 Jokes 11 Customize 12 Tangling .. 12.1 .emacs.el .. 12.2 eshell/alias 13 Portability .. 13.1 Windows ..... 13.1.1 Testing ..... 13.1.2 Helper Bindings ..... 13.1.3 AutoHotKey .. 13.2 OSX ..... 13.2.1 Keyboard 14 Reminders 15 Confessions 1 Start Up ══════════ There are things that must occur during start… *before* everything else. Load the newer version of a file: bytecode or lisp. This says a lot. In the users guide it explains why you may want this turned off. That way you can develop code and try it out to see how it works and comare it to the old version which had been byte-compiled. I am not doing that here. ┌──── │ (setq load-prefer-newer t) └──── 2 Run-time ══════════ Reproducibility is both the foundation of all good science, and, the thing that allows us to tell, and enjoy, jokes. This system is a little of both Paging through hundreds of Emacs related posts in my memory banks, there is a common decision shared with the reader /not/ to upgrade the Emacs version. This could be out of laziness, which makes total sense, and another good reason is that every new release brings change. Despite the fact that we are subject to decay, which is /just/ change, most humans don't like either. Change often brings pain, and hard work. To help alleviate some of the pain, this system will attempt to capture its configuration at a particular state in time to facilitate reproducibility. In practice, it will be a bit liberal, though. This system will only start with the correct version of Emacs, v24.4 ┌──── │ (defun gcr/emacs-version-check () │ "Enforce version compliance." │ (interactive) │ (when (not (and (= emacs-major-version 24) │ (= emacs-minor-version 4))) │ (error │ "Incorrect Emacs runtime. Expected v24.4. Found v%s.%s" │ (number-to-string emacs-major-version) │ (number-to-string emacs-minor-version)))) │ (gcr/emacs-version-check) └──── 3 Provisioning ══════════════ 3.1 Background ────────────── In /the old days/, the way that you managed software packages for Emacs was to do it manually because there was no software distribution system available. In my case, I just put everything inside of a Subversion project and moved on. That actually worked fine, but I didn't like committing compiled code, and handling updates was always a hassle depending on how files and the directory structure had changed. Fortunately that all changed with the introduction of Package and ELPA. When I first cut my system over to ELPA I went with GNU ELPA and Marmalade. Eventually I found that they weren't the right thing for me since the former had a very small collection and the latter, strangely, had exactly what I wasn't looking for. About that time, MELPA was starting to really gain momentum. MELPA is really a community and a belief-system in addition to being a package repository. They value structure and form, and make sure that the package builds, and then they do the building for you. They are doing great things to create, nurture, and guide the community to define a higher standard for package quality. Around that time, too I got fed up with manually installing and worrying whether I had the packages installed or not, so after figuring that there was something better than some custom code that I wrote, I looked at Cask. Cask is a declarative approach for expressing dependencies. That sounds fancy but it isn't. Cask just makes it really easy to obtain ELPA packages from different repositories. One reason that I really like is that you see all of your packages in a single place rather than sprinkled about all over your initialization file. It also lowers the bar for new users to with just one line of code add a new repository. Something funny happened though, the more I learned about Emacs and the community, the more I found the need to manage software not hosted in MELPA. MELPA is perfect at what it does, and it is still evolving. Rather than try to plan for everything, they decided to solve 80% of most problems for most people and that is super. Now they are looking at how to handle versioned packages by hosting a stable repository that uses Git tags, and that is super, too. What about software that doesn't live in a package though? You start finding code all over not in packages. EmacsWiki is the exception given that MELPA supports that. What about random Emacs-Lisp code you find out on the 'Net? That question got me motivated to learn about other people's approaches for package management. That is where I learned about EL-Get. EL-Get is powerful, and flexible, and concise. What it lacks in community momentum, it makes up for in raw power. When I find code that doesn't live in packages, and may never, then I start setting up EL-Get to grab it for me. Based upon what I've read, it had its time in the sun. Its power is still true, and its value is a great, because it truly succeeds at the goals that it set out on. The first time I set up Cask, it was the only option for easily specifying which repository you wanted to use for installing a package. It was great. Then, I got the bug to be able to easily collaborate with others by sending them a single initialization file. Kind of a theoretical goal, but there is *one* person with whom I want to collaborate that makes it completely make sense. More than a year after switching from Subversion to Cask, I dug into the options out there today. My foray into EL-Get was kind of a mistake, since its role had changed in the community between then and its inception. I spent a lot of time not being productive there. Then I figured that Cask would be fine, but at the time it did not run easily on Windows, which is really important to me. Based on that, I quit pursuing Cask as an option. From what I read, Cask does now run easily on Windows, but I am not revisiting it for now. One mistake that I made here was assuming that recipes would be the same between EL-Get and Cask. Doh! Of course they wouldn't be. The nice side-effect here though was learning the power of EL-Get. It is very powerful. The great news as of 24.4 is that Package inside of Emacs allows you to specify the source repository from which to install a package. This is a hugely important feature and I am thrilled on all user's behalf's. The old problem was that sometimes you might want the stable version of Foo and something you want the development version of Foo. The problem was that you never quite knew which one you would get because the packages lived in *both* repositories! Now, it is no longer an issue, and one of the reasons that I don't need to use Cask anymore. Package should do it all, and it will, below. That was my plan. It failed. My approach was simple. First I identified all of the packages that I used that were available on MELPA Stable. Then added MELPA Stable as a repository and added all of those packages to package-pinned-packages'. To help me out, I also added a separate entry just to pull MELPA packages that were not ELPA packages. On this setup, it worked about %75 of the time. I couldn't figure out why. I tried every permutation. I removed entries. It wasn't enough. It never worked right. Here is what it did: What is happening is simple • Delete the ELPA directory • Start this system • Packages that are pinned to MELPA Stable are installed from MELPA Long ago Steve Purcell asked someone on GitHub why they want stable. I don't recall the exact conversation. Perhaps I asked something. His answer was really simple. It was something like "Going with the TRUNK tends to be fine. If it breaks, it usually gets fixed quickly". I understood. I just *really* wanted to try the /reproducible research/ thing with this system. I was very gung-ho about it. It didn't work out though. Then I started loading everything from MELPA. At that point, everything worked _perfectly_. I tested it 5 times. I look forward to seeing how it works out in the future. It is certainly consistent with what Purcell shared. 3.2 Steps ───────── 3.2.1 Package ╌╌╌╌╌╌╌╌╌╌╌╌╌ Before doing any work with Package it must be initialized. Failure to do so is the easiest way to waste time and achieve nothing. ┌──── │ (package-initialize) └──── Use the Org ELPA repository. I won't lock down the version here, I just want it to be stable. In the Org configuration, I'll at warning for specific features. ┌──── │ (add-to-list 'package-archives │ '("org" . "http://orgmode.org/elpa/") t) └──── GNU stuff is always good. ┌──── │ (add-to-list 'package-archives │ '("gnu" . "http://elpa.gnu.org/packages/")) └──── MELPA is critical. ┌──── │ (add-to-list 'package-archives │ '("melpa" . "http://melpa.org/packages/") t) └──── If Package+ is not installed, then install it. First the package list has to be refreshed so that Package knows about the new packages. ┌──── │ (package-refresh-contents) │ (unless (package-installed-p 'package+) │ (package-install 'package+)) └──── This is the list of packages that should be installed automatically and loaded. Any packages not listed here that Package+ finds are removed. ┌──── │ (package-manifest │ 'ace-jump-mode │ 'ace-link │ 'ace-window │ 'aggressive-indent │ 'alert │ 'anchored-transpose │ 'anzu │ 'ascii-art-to-unicode │ 'auctex │ 'auto-complete │ 'auto-complete-chunk │ 'autotetris-mode │ 'boxquote │ 'clips-mode │ 'ctable │ 'diff-hl │ 'diminish │ 'dired-details+ │ 'dired-imenu │ 'ess │ 'ess-R-data-view │ 'ess-R-object-popup │ 'esup │ 'exec-path-from-shell │ 'expand-region │ 'f │ 'figlet │ 'fill-column-indicator │ 'flx-ido │ 'flycheck │ 'fuzzy │ 'geiser │ 'google-this │ 'graphviz-dot-mode │ 'highlight-tail │ 'htmlize │ 'ido-hacks │ 'ido-ubiquitous │ 'ido-vertical-mode │ 'imenu+ │ 'imenu-anywhere │ 'inlineR │ 'json-reformat │ 'key-chord │ 'langtool │ 'lexbind-mode │ 'magit │ 'markdown-mode │ 'metaweblog │ 'move-text │ 'multiple-cursors │ 'neotree │ 'nyan-mode │ 'ob-sml │ 'org-ac │ 'org-plus-contrib │ 'osx-browse │ 'package+ │ 'pandoc-mode │ 'plantuml-mode │ 'polymode │ 'pos-tip │ 'pretty-mode │ 'projectile │ 'r-autoyas │ 'rainbow-delimiters │ 's │ 'smartparens │ 'smex │ 'sml-mode │ 'smooth-scrolling │ 'solarized-theme │ 'sparkline │ 'sqlup-mode │ 'string-edit │ 'stripe-buffer │ 'undo-tree │ 'unicode-fonts │ 'vagrant │ 'web-mode │ 'wrap-region │ 'writegood-mode │ 'xml-rpc │ 'yaml-mode │ ) └──── Why doesn't the F' package get loaded correctly? The directory is in the load-path'. The auto-load is in there. It is only on my machine. I will look into this. This manual step used to use load'. That was a mistake. It relied upon specifying the package directory. The package directory can change on every install so I had to update this line every time. That was stupid. load-library' searches for libraries by name. It works. ┌──── │ (load-library "f") └──── 3.2.2 el-get ╌╌╌╌╌╌╌╌╌╌╌╌ EL-Get handles things that don't easily fit anywhere else. Initialize EL-Get. ┌──── │ (add-to-list 'load-path "~/.emacs.d/el-get/el-get") │ │ (unless (require 'el-get nil 'noerror) │ (with-current-buffer │ (url-retrieve-synchronously │ "https://raw.githubusercontent.com/dimitri/el-get/master/el-get-install.el") │ (goto-char (point-max)) │ (eval-print-last-sexp))) └──── ┌──── │ (setq gcr/el-get-packages nil) └──── org-show' [1] looks like the prefect presentation tool for me. jkitchin is just… he is one a sweet wavelength. This presentation tool makes it really, really easy to present in a very /Emacs/ way. It is worth discussing a bit why I got this module in this manner: • org-show' is distributed as an org file • It requires tangling to produce a emacs-lisp file for utilization by emacs • John explains how to do so in the file itself via org-babel-load-file' • This works fine on a vanilla, org' setup • I do not have a vanilla, org' setup • I do not know the issue and I am not going to debug it for now • The approach here than is to: • Obtain the file • Start emacs' with the raw' setup defined in this document, which is nothing but org' … and from there, tangle org-show' • It is manual and that is OK for now ┌──── │ (add-to-list │ 'el-get-sources │ '(:name org-show │ :type http │ :url "https://raw.githubusercontent.com/jkitchin/jmax/master/org/org-show.org" │ :website "https://github.com/jkitchin/jmax/blob/master/org/org-show.org" │ :description "simple presentations in org-mode")) │ (add-to-list 'gcr/el-get-packages 'org-show) └──── Make it really easy to remind yourself and others what EMACS really stands for (in this case it is fun). ┌──── │ (add-to-list │ 'el-get-sources │ '(:name emacs-name │ :type http │ :url "http://www.splode.com/~friedman/software/emacs-lisp/src/emacs-name.el" │ :features emacs-name │ :autoloads nil │ :website "http://www.splode.com/" │ :description "emacs acronym expansions")) │ (add-to-list 'gcr/el-get-packages 'emacs-name) └──── It is not good to flame people on the Internet. It is good to /know/ what it is all about, and here is a way to see some examples of the absurdity of it all. ┌──── │ (add-to-list │ 'el-get-sources │ '(:name flame │ :type http │ :url "http://www.splode.com/~friedman/software/emacs-lisp/src/flame.el" │ :features flame │ :autoloads nil │ :website "http://www.splode.com/" │ :description "automatic generation of flamage, as if we needed more")) │ (add-to-list 'gcr/el-get-packages 'flame) └──── People love horoscopes, so, provide them. ┌──── │ (add-to-list │ 'el-get-sources │ '(:name horoscope │ :type http │ :url "http://www.splode.com/~friedman/software/emacs-lisp/src/horoscope.el" │ :features horoscope │ :autoloads t │ :website "http://www.splode.com/" │ :description "generate horoscopes")) │ (add-to-list 'gcr/el-get-packages 'horoscope) └──── James Parry [2] must always be honored. ┌──── │ (add-to-list │ 'el-get-sources │ '(:name kibologize │ :type http │ :url "http://www.splode.com/~friedman/software/emacs-lisp/src/kibologize.el" │ :features kibologize │ :autoloads nil │ :website "http://www.splode.com/" │ :description "generate ravings about kibology, in the style of kibo")) │ (add-to-list 'gcr/el-get-packages 'kibologize) └──── You might not always remember your shopping list, but we will remember it for you… though not necessarily for wholesale. ┌──── │ (add-to-list │ 'el-get-sources │ '(:name shop │ :type http │ :url "http://www.splode.com/~friedman/software/emacs-lisp/src/shop.el" │ :features shop │ :autoloads nil │ :website "http://www.splode.com/" │ :description "generate random shopping lists")) │ (add-to-list 'gcr/el-get-packages 'shop) └──── Do you remember when those great AT&T adds were on television and it changed your life and bought you a kitten? You will. ┌──── │ (add-to-list │ 'el-get-sources │ '(:name youwill │ :type http │ :url "http://www.splode.com/~friedman/software/emacs-lisp/src/youwill.el" │ :features youwill │ :autoloads t │ :website "http://www.splode.com/" │ :description "generate meaningless marketing hype")) │ (add-to-list 'gcr/el-get-packages 'youwill) └──── A swimming-pool screen-saver. ┌──── │ (add-to-list │ 'el-get-sources │ '(:name swimmers │ :type http │ :url "http://www.cb1.com/~john/computing/emacs/lisp/games/swimmers.el" │ :features swimmers │ :autoloads nil │ :website "http://www.cb1.com/~john/" │ :description "Draw a swimming-pool screensaver")) │ (add-to-list 'gcr/el-get-packages 'swimmers) └──── ┌──── │ (add-to-list 'el-get-sources '(:name emacs-uuid │ :type github │ :pkgname "nicferrier/emacs-uuid")) │ (add-to-list 'gcr/el-get-packages 'emacs-uuid) │ (add-to-list 'el-get-sources '(:name emacs-world-time-mode │ :type github │ :pkgname "nicferrier/emacs-world-time-mode")) │ (add-to-list 'gcr/el-get-packages 'emacs-world-time-mode) └──── Today the recipe didn't work, el-get' couldn't find it. That is pretty bizarre because /nothing changed/. The recipe still lives here [3]. Because this is broken for some unknown reason, I'm omitting it and will simply fix it the /next/ time that I want to run it. (add-to-list 'gcr/el-get-packages 'sicp)' As el-get to make sure that those desired packages are installed. ┌──── │ (el-get 'sync gcr/el-get-packages) └──── 4 Ends & Means ══════════════ There are so many ways to customize a system. Is intent or pragmatics more important? In my philosophy, the nature of the /end/ is contained within the properties of the /means/ themselves. They are inseparable. The traits are the fundamental aspects of this system. They are things that are critical, they are *everything*. Here my goal is to capture both the means and the ends. These are the minimum fundamental features to allow for the fluid delivery and execution of the creative experience within this medium. The capture occurs sequentially. The ends are listed first though, because they are much more meaningful and inspiring to me than the means, at least in "listed here form". Their execution, of course, is much more visceral and fun! The means used to be broken up into highly categorical sections. It made sense, but it didn't read well. It might make sense from a reference perspective, but that was about it. This document focuses more on the flow. Since the fundamental means /ought/ to be concise, they are intended to be read at a single sitting. 5 Ends (ALEC) ═════════════ This system has changed who I am and how I think. Because it is easier to focus on the tools rather than the intent, on the means versus the ends, I focus on this system, this configuration of Emacs. My system is a provider, a realization, of a language for expressing creativity. 𝔸𝕃𝔼ℂ. ALEC's a Language for Expressing Creativity. That is a truly and utterly beautiful thing to ponder. The expression of creativity is why we are born human. Five of our senses go out into the world searching, always searching. In our time-space, the expressions that may be consumed by the eye (paintings, graphic arts) and consumed by the ear (music) are so, so lovely, and easy for us to understand (How do you address someone whose /true/ name is Symphony?). We are here to let that voice sing, and we want all five senses to help do it, for the maximization of expressivity. The song, that sweet celestial song, is sometimes more difficult for people to hear. The honey-kissed embrace of one's love feels different than a song, and different than laughing at a joke, but they are all the creative act. Gardening, selling, collecting, tending… they are all part of the creative act that makes us again be born human. We always seem to focus on the configuration of those actions (time, space, causality, and identity), the build of those tools, necessary to perform the creative act. With time and patience, we will know the true nature of things. Part of the path is indeed attaining mastery. Mastery over ourselves, mostly, by some way that is gentle and kind. That action, that attempt, for me, has partially culminated in the aggregation of a lifetime of mastery of tools and programming languages and ideas and studies and training and collaboration and mystery and magic and laughing, in this birth, in the artifact called ALEC, and ALEC can only be expressed, for me, for now, with Emacs. This system is no longer "Emacs". It is not its disparate packages. They are tools, yes, and more importantly, they are expressions of creativity. Together in Emacs, in ALEC, they are composed, like parts of a symphony, together, to allow for the ultimate in the act of creative expression. The tools themselves possess these traits, both in their implementation and their intent. That is traditional, in that, the properties and traits expressed by these "words", these compositional units, have the properties and traits of the things expressed by these "words". "Words" is the most expressive element that I can think of right now, for things that can be atoms, and yet be combined to form sentences, something larger and more expressive, in a particular language, which itself can quite magically express ideas, about itself, or about anything else in existence. It is like watching a beautiful lotus blooming, spreading its pedals, having been nourished by the fertile soil, protected in its pond, knowing that it must strive to reach higher, nurtured by Mother Sun. The very act, the ultimate act of creative expression, that very action contains itself and is culminated by itself. It is that which it is trying to achieve, and to be that, is to do that, for itself and for all of creation. This ultimate act of creative expression, is present in the manifestation of Emacs and the packages and the users who come together to form a perfect symphony of creative expression in a form that may be captured and represented as a computer file, so humble and modest, just like a small seed of a proud and mighty Redwood tree that will eventually reach hundreds and hundreds of feet into the sky and towards Mother Sun, contains that which it will become in it's own existence, so too does it contain its own beautiful destiny in the seeds of beauty and creative expression that are produced with ALEC (in every form, not just the one described by this document of course!). The blossoming of the expression of the computational act, and the petals that opened in the form of the Turing's machine, Church's Lambda calculus, and Post's Tag System, are beautiful, and still, are only petals, that carry the sweet fragrance, because a fragrance is part of a moment, which is finite, as is every configuration of this reality. The beauty is still as sweet. The key is seeing the inherent beauty, the source without start and without end, and then being able to see that in everyone and everything. That thing, which was present before the expression of creativity, and will exist after it, which is not subject to the laws of time, space, causality, and identity, is the point that everyone surely wishes to re-visit. That quest, /the/ great motivator of the most softly spoken and heartfelt desire, itself is surely yet another expression of /that which is gentle and kind/. The steps taken on that quest, despite being driven by that perfect intent, are /still/ subject to the four boundaries of this reality. Those actions, defined by configurations, like the petals of the lotus, retaining its sweet fragrance, can, will, and must fade, but, we will shine on in the sweet embrace of Mother Sun, knowing that loving and warm embrace of sweet perfection, in our one, and true, home. 5.1 The desire ────────────── "I want". If only all conversations would start out with a clear goal in mind. All too often we waste our own, and other people's time talking and simply trying to figure out what it is what we want. For most of us, "it", is that thing that will solve all of our problems in life and make us happy. Technology is no exception. The perfect integrated development environment is a topic of constant conversation. For good reason, for most of us it is our only tool. Unlike carpenters and wood-workers who have a bevy of interesting and delightful tools, we are stuck with but one. Fortunately for us, our singular tool allows limitless creation, of tools and more. Alan Kay said it so well [4]: The computer is a medium that can dynamically simulate the details of any other medium, including media that cannot exist physically. It is not a tool, although it can act like many tools. The computer is the first metamedium, and as such it has degrees of freedom for representation and expression never before encountered and as yet barely investigated. The protean nature of the computer is such that it can act like a machine or like a language to be shaped and exploited. Even more succinctly, my measure of success is to: To provide a self-suportable environment in which the creation and conservation of computer files may occur with ease As of writing, although there are many nice options out there, none of them come within even light-years, of power that you are granted for working with a computer as that metamedium, that GNU Emacs [5]. With that in mind, the following is what I actually want to do with it. 5.2 The story ───────────── The creativity that you apply and capture to assemble your system… this is where all of the fun stuff is. Let me elaborate, everything in your artifacts are valuable because they tell the story. Actually, they tell the story about a story, a story that has yet to occur and also a story that has previously occurred. It is here, where the actions lives, that all of those things are learned, practiced, suffered accordingly from, and reveled in! In other words, it is yet another story, a fun one. If you haven't noticed by now, either by hearing rumors, reading accounts, or learning of it yourself: human beings are story-oriented. Your ability to successfully function in and contribute to society will be directly proportional to your ability to listen to stories, tell others' stories, live your life such that you have new stories to tell, and capture them in some form of persistent storage. Stories grant us the power to learn from others wisdom that was painfully acquired thousands of years ago, and it gives you a chance to contribute the results of your hard work, for the future of humanity, too. A belief system about the value of story-telling is essential, critical, and mandatory to successfully achieve your goals with literate programming. As I change, the story will change, and the action will change. The cycle will never end. Nevertheless, I will attempt to do my best here with the good part of me being a flawless, rational, and logical human being to: • Deliver a supportable system • Deliver an adaptable system • Deliver an expandable system 5.3 Inspirations ──────────────── Eric Weisstein: Creator of MathWorld [6] 6 Means ═══════ These are features that I consider critical to getting this system up and running. The original intent of this heading was to identify the minimal core configuration required to build this very system. It was more of the "keep it lean" line of thinking, entirely without justification of course. An interesting thing happened, learning. Once that core is built up, it just makes total, total sense to build on it. It feels totally natural, and even "obvious" to do so. Not out of boredom, but rather, out of ease-of-use. Because of this learning, I am a lot more comfortable with including things that before I felt were superficial. That is the power in the composition of the layers of ideas and features, they become means that build upon each others. The hardest part is knowing the best way to delineate those layers, if at all. Perhaps they should simply best be just enjoy, and not pondered or revealed. My personal goal is to keep the tangling of this document to less than 30 seconds. It needs to be fast to allow the operator to remain /in the flow/ and to maximize creative expression. This is a human problem solved by a technological implementation. It is a work in progress. Whatever the case, I will keep to this goal because without it, the operators starts to be unnecessary constricted. No matter what… no matter what, the tangling must be done in 30 seconds or less. That is the one, only, and single thing that I ever allow influence the design and implementation of ALEC in this manifestation because to do anything else would be to seriously constrain its operator. 6.1 Functions & Constants ───────────────────────── ┌──── │ (defun gcr/untabify-buffer () │ "For untabifying the entire buffer." │ (interactive) │ (untabify (point-min) (point-max))) │ │ (defun gcr/untabify-buffer-hook () │ "Adds a buffer-local untabify on save hook" │ (interactive) │ (add-hook │ 'after-save-hook │ (lambda () (gcr/untabify-buffer)) │ nil │ 'true)) │ │ (defun gcr/disable-tabs () │ "Disables tabs." │ (setq indent-tabs-mode nil)) │ │ (defmacro gcr/on-gnu/linux (statement &rest statements) │ "Evaluate the enclosed body only when run on GNU/Linux." │ (when (eq system-type 'gnu/linux) │ ,statement │ ,@statements)) │ │ (defmacro gcr/on-osx (statement &rest statements) │ "Evaluate the enclosed body only when run on OSX." │ (when (eq system-type 'darwin) │ ,statement │ ,@statements)) │ │ (defmacro gcr/on-gnu/linux-or-osx (statement &rest statements) │ "Evaluate the enclosed body only when run on GNU/Linux or OSX." │ (when (or (eq system-type 'gnu/linux) │ (eq system-type 'darwin)) │ ,statement │ ,@statements)) │ │ (defmacro gcr/on-windows (statement &rest statements) │ "Evaluate the enclosed body only when run on Microsoft Windows." │ (when (eq system-type 'windows-nt) │ ,statement │ ,@statements)) │ │ (defmacro gcr/on-gui (statement &rest statements) │ "Evaluate the enclosed body only when run on GUI." │ (when (display-graphic-p) │ ,statement │ ,@statements)) │ │ (defmacro gcr/not-on-gui (statement &rest statements) │ "Evaluate the enclosed body only when run on GUI." │ (when (not (display-graphic-p)) │ ,statement │ ,@statements)) │ │ (defmacro gcr/diminish (mode) │ "Diminish this mode after it is loaded." │ (interactive) │ (eval-after-load ,mode │ (diminish ,mode))) │ │ (defvar gcr/delete-trailing-whitespace-p t │ "Should trailing whitespace be removed?") │ │ (defun gcr/delete-trailing-whitespace () │ "Delete trailing whitespace for everything but the current line. │ │ If gcr/delete-trailing-whitespace-p' is non-nil, then delete the whitespace. │ This is useful for fringe cases where trailing whitespace is important." │ (interactive) │ (when gcr/delete-trailing-whitespace-p │ (let ((first-part-start (point-min)) │ (first-part-end (point-at-bol)) │ (second-part-start (point-at-eol)) │ (second-part-end (point-max))) │ (delete-trailing-whitespace first-part-start first-part-end) │ (delete-trailing-whitespace second-part-start second-part-end)))) │ │ (defun gcr/set-org-babel-default-header-args (property value) │ "Easily set system header arguments in org mode. │ │ PROPERTY is the system-wide value that you would like to modify. │ │ VALUE is the new value you wish to store. │ │ Attribution: URL http://orgmode.org/manual/System_002dwide-header-arguments.html#System_002dwide-header-arguments'" │ (setq org-babel-default-header-args │ (cons (cons property value) │ (assq-delete-all property org-babel-default-header-args)))) │ │ (defun gcr/set-org-babel-default-inline-header-args (property value) │ "See gcr/set-org-babel-default-header-args'; same but for inline header args." │ (setq org-babel-default-inline-header-args │ (cons (cons property value) │ (assq-delete-all property org-babel-default-inline-header-args)))) │ │ (defun gcr/set-org-babel-default-header-args:R (property value) │ "See gcr/set-org-babel-default-header-args'; same but for R. │ │ This is a copy and paste. Additional languages would warrant a refactor." │ (setq org-babel-default-header-args:R │ (cons (cons property value) │ (assq-delete-all property org-babel-default-header-args:R)))) │ │ (defun gcr/ispell-org-header-lines-regexp (h) │ "Help ispell ignore org header lines." │ (interactive) │ (cons (concat "^#\\+" h ":") ".$")) │ │ (defun gcr/ispell-a2isra (block-def) │ "Add to the ispell skip region alist the BLOCK-DEF." │ (interactive) │ (add-to-list 'ispell-skip-region-alist block-def)) │ │ (defun gcr/insert-timestamp () │ "Produces and inserts a full ISO 8601 format timestamp." │ (interactive) │ (insert (format-time-string "%Y-%m-%dT%T%z"))) │ │ (defun gcr/insert-timestamp* () │ "Produces and inserts a near-full ISO 8601 format timestamp." │ (interactive) │ (insert (format-time-string "%Y-%m-%dT%T"))) │ │ (defun gcr/insert-datestamp () │ "Produces and inserts a partial ISO 8601 format timestamp." │ (interactive) │ (insert (format-time-string "%Y-%m-%d"))) │ │ (defun gcr/comment-or-uncomment () │ "Comment or uncomment the current line or selection." │ (interactive) │ (cond ((not mark-active) (comment-or-uncomment-region (line-beginning-position) │ (line-end-position))) │ ((< (point) (mark)) (comment-or-uncomment-region (point) (mark))) │ (t (comment-or-uncomment-region (mark) (point))))) │ │ (defun gcr/no-control-m () │ "Aka dos2unix." │ (interactive) │ (let ((line (line-number-at-pos)) │ (column (current-column))) │ (mark-whole-buffer) │ (replace-string " │ " "") │ (goto-line line) │ (move-to-column column))) │ │ (defun gcr/save-all-file-buffers () │ "Saves every buffer associated with a file." │ (interactive) │ (dolist (buf (buffer-list)) │ (with-current-buffer buf │ (when (and (buffer-file-name) (buffer-modified-p)) │ (save-buffer))))) │ │ (defun gcr/kill-other-buffers () │ "Kill all other buffers." │ (interactive) │ (mapc 'kill-buffer (delq (current-buffer) (buffer-list)))) └──── Might be worth investing in new behavior here such that: • When the cursor is inside of a comment block, call comment-indent-new-line' • Else, call sp-newline' ┌──── │ (defun gcr/newline () │ "Locally binds newline." │ (local-set-key (kbd "RET") 'sp-newline)) └──── ┌──── │ (defun gcr/describe-thing-in-popup () │ "Display help information on the current symbol. │ │ Attribution: URL http://www.emacswiki.org/emacs/PosTip' │ Attribution: URL http://blog.jenkster.com/2013/12/popup-help-in-emacs-lisp.html'" │ (interactive) │ (let* ((thing (symbol-at-point)) │ (help-xref-following t) │ (description (with-temp-buffer │ (help-mode) │ (help-xref-interned thing) │ (buffer-string)))) │ (gcr/on-gui (pos-tip-show description nil nil nil 300)) │ (gcr/not-on-gui (popup-tip description │ :point (point) │ :around t │ :height 30 │ :scroll-bar t │ :margin t)))) │ │ (defun gcr/indent-curly-block (&rest _ignored) │ "Open a new brace or bracket expression, with relevant newlines and indent. Src: https://github.com/Fuco1/smartparens/issues/80" │ (newline) │ (indent-according-to-mode) │ (forward-line -1) │ (indent-according-to-mode)) │ │ (defun beginning-of-line-dwim () │ "Toggles between moving point to the first non-whitespace character, and │ the start of the line. Src: http://www.wilfred.me.uk/" │ (interactive) │ (let ((start-position (point))) │ ;; see if going to the beginning of the line changes our position │ (move-beginning-of-line nil) │ │ (when (= (point) start-position) │ ;; we're already at the beginning of the line, so go to the │ ;; first non-whitespace character │ (back-to-indentation)))) │ │ (defun gcr/lazy-new-open-line () │ "Insert a new line without breaking the current line." │ (interactive) │ (beginning-of-line) │ (next-line) │ (newline) │ (previous-line)) │ │ (defun gcr/smart-open-line () │ "Insert a new line, indent it, and move the cursor there. │ │ This behavior is different then the typical function bound to return │ which may be open-line' or newline-and-indent'. When you call with │ the cursor between ^ and$, the contents of the line to the right of │ it will be moved to the newly inserted line. This function will not │ do that. The current line is left alone, a new line is inserted, indented, │ and the cursor is moved there. │ │ Attribution: URL http://emacsredux.com/blog/2013/03/26/smarter-open-line/'" │ (interactive) │ (move-end-of-line nil) │ (newline-and-indent)) │ │ (defun gcr/narrow-to-region* (boundary-start boundary-end fun) │ "Edit the current region in a new, cloned, indirect buffer. │ │ This function is responsible for helping the operator to easily │ manipulate a subset of a buffer's contents within a new buffer. The │ newly created clone buffer is created with clone-indirect-buffer', │ so all of its behaviors apply. You may care specifically about the │ fact that the clone is really just a 'view' of the source buffer, so │ actions performed within the source buffer or its clone(s) are │ actually occurring only within the source buffer itself. When the │ dynamic extent of this function is entered, the operator is prompted │ for a function to call to make upon entering the new buffer. The intent │ is to specify the desired mode for the new buffer, for example by │ calling scheme-mode', but any function may be called. │ │ The subset chosen for manipulation is narrowed by │ narrow-to-region'. When the clone buffer is created, the lines in │ which the start and end of the boundary occur are included at the │ end the new clone buffer name to serve as a reminder for its │ 'true source'. The intent is to facilitate going back from the clone │ buffer to the source buffer with knowledge of where it originated. │ │ BOUNDARY-START and BOUNDARY-END are provided by delegation of this │ function to interactive'. FUN is provided interactively by the │ operator via the modeline in the same manner. See Info node │ (elisp) Eval' for more on why funcall' was used here instead of │ eval' for calling the selected function. │ │ Attribution: URL http://demonastery.org/2013/04/emacs-narrow-to-region-indirect/' │ Attribution: URL http://paste.lisp.org/display/135818Attribution'" │ (interactive "*r\naMode name? ") │ (let* ((boundary-start (if (< boundary-start 1) (point-min) │ boundary-start)) │ (boundary-end (if (<= boundary-end boundary-start) (point-max) │ boundary-end)) │ (new-name (concat │ (buffer-name) │ "⊃" │ (number-to-string (line-number-at-pos boundary-start)) │ "-" │ (number-to-string (line-number-at-pos boundary-end)))) │ (buf-name (generate-new-buffer-name new-name)) │ (fun (if (fboundp fun) fun │ 'fundamental-mode))) │ (with-current-buffer (clone-indirect-buffer buf-name +1 +1) │ (narrow-to-region boundary-start boundary-end) │ (deactivate-mark) │ (goto-char (point-min)) │ (funcall fun)))) │ │ (defun gcr/insert-ellipsis () │ "Insert an ellipsis into the current buffer." │ (interactive) │ (insert "…")) │ │ (defun gcr/insert-noticeable-snip-comment-line () │ "Insert a noticeable snip comment line (NSCL)." │ (interactive) │ (if (not (bolp)) │ (message "I may only insert a NSCL at the beginning of a line.") │ (let ((ncl (make-string 70 ?✂))) │ (newline) │ (previous-line) │ (insert ncl) │ (comment-or-uncomment-region (line-beginning-position) (line-end-position))))) │ │ (defun gcr/dired-copy-filename () │ "Push the path and filename of the file under the point to the kill ring. │ │ Attribution: URL https://lists.gnu.org/archive/html/help-gnu-emacs/2002-10/msg00556.html'" │ (interactive) │ (message "Added %s to kill ring" (kill-new (dired-get-filename)))) │ │ (defun gcr/dired-copy-path () │ "Push the path of the directory under the point to the kill ring." │ (interactive) │ (message "Added %s to kill ring" (kill-new default-directory))) │ │ (defun gcr/file-exists-not-symlink (f) │ "True if F exists and is not a symlink." │ (interactive) │ (and (file-exists-p f) │ (not (file-symlink-p f)))) │ │ (defun gcr/file-exists-is-symlink (f) │ "True if F exists and is a symlink." │ (interactive) │ (and (file-exists-p f) │ (file-symlink-p f))) │ │ (progn │ (defvar my-read-expression-map │ (let ((map (make-sparse-keymap))) │ (set-keymap-parent map read-expression-map) │ (define-key map [(control ?g)] #'minibuffer-keyboard-quit) │ (define-key map [up] nil) │ (define-key map [down] nil) │ map)) │ │ (defun my-read--expression (prompt &optional initial-contents) │ (let ((minibuffer-completing-symbol t)) │ (minibuffer-with-setup-hook │ (lambda () │ (emacs-lisp-mode) │ (use-local-map my-read-expression-map) │ (setq font-lock-mode t) │ (funcall font-lock-function 1)) │ (read-from-minibuffer prompt initial-contents │ my-read-expression-map nil │ 'read-expression-history)))) │ │ (defun my-eval-expression (expression &optional arg) │ (interactive (list (read (my-read--expression "")) │ current-prefix-arg)) │ (if arg │ (insert (pp-to-string (eval expression lexical-binding))) │ (pp-display-expression (eval expression lexical-binding) │ "*Pp Eval Output*")))) │ │ (defun gcr/util-ielm () │ "Personal buffer setup for ielm. │ │ Creates enough space for one other permanent buffer beneath it." │ (interactive) │ (split-window-below -20) │ (other-window 1) │ (ielm) │ (set-window-dedicated-p (selected-window) t)) │ │ (defun gcr/util-eshell () │ "Personal buffer setup for eshell. │ │ Depends upon gcr/util-ielm' being run first." │ (interactive) │ (split-window-below -10) │ (other-window 1) │ (eshell) │ (set-window-dedicated-p (selected-window) t)) │ │ (defvar gcr/util-state nil "Track whether the util buffers are displayed or not.") │ │ (defun gcr/util-state-toggle () │ "Toggle the util state." │ (interactive) │ (setq gcr/util-state (not gcr/util-state))) │ │ (defun gcr/util-start () │ "Perhaps utility buffers." │ (interactive) │ (gcr/util-ielm) │ (gcr/util-eshell) │ (gcr/util-state-toggle)) │ │ (defun gcr/util-stop () │ "Remove personal utility buffers." │ (interactive) │ (if (get-buffer "*ielm*") (kill-buffer "*ielm*")) │ (if (get-buffer "*eshell*") (kill-buffer "*eshell*")) │ (gcr/util-state-toggle)) │ │ (defun gcr/ielm-auto-complete () │ "Enables auto-complete' support in \\[ielm]. │ │ Attribution: URL http://www.masteringemacs.org/articles/2010/11/29/evaluating-elisp-emacs/'" │ (setq ac-sources '(ac-source-functions │ ac-source-variables │ ac-source-features │ ac-source-symbols │ ac-source-words-in-same-mode-buffers)) │ (add-to-list 'ac-modes 'inferior-emacs-lisp-mode) │ (auto-complete-mode 1)) │ │ (defun gcr/uuid-string () │ "Insert a string form of a UUID." │ (interactive) │ (insert (uuid-to-stringy (uuid-create)))) │ │ (defun yf/org-electric-dollar nil │ "When called once, insert \$$\$$ and leave point in between. │ When called twice, replace the previously inserted \$$\$$ by one $. │ │ from Nicolas Richard │ Date: Fri, 8 Mar 2013 16:23:02 +0100 │ Message-ID: <87vc913oh5.fsf@yahoo.fr>" │ (interactive) │ (if (and (looking-at "\\\\)") (looking-back "\\\$$")) │ (progn (delete-char 2) │ (delete-char -2) │ (insert "")) │ (insert "\\(\$$") │ (backward-char 2))) │ │ (defun endless/sharp () │ "Insert #' unless in a string or comment. │ │ SRC: URL http://endlessparentheses.com/get-in-the-habit-of-using-sharp-quote.html?source=rss'" │ (interactive) │ (call-interactively #'self-insert-command) │ (let ((ppss (syntax-ppss))) │ (unless (or (elt ppss 3) │ (elt ppss 4)) │ (insert "'")))) │ │ (defun gcr/chs () │ "Insert opening \"cut here start\" snippet." │ (interactive) │ (insert "--8<---------------cut here---------------start------------->8---")) │ │ (defun gcr/che () │ "Insert closing \"cut here end\" snippet." │ (interactive) │ (insert "--8<---------------cut here---------------end--------------->8---")) │ │ (defmacro gcr/measure-time (&rest body) │ "Measure the time it takes to evaluate BODY. │ │ Attribution Nikolaj Schumacher: URL https://lists.gnu.org/archive/html/help-gnu-emacs/2008-06/msg00087.html'" │ (let ((time (current-time))) │ ,@body │ (message "%.06f" (float-time (time-since time))))) │ │ (defun gcr/create-non-existent-directory () │ "Attribution URL: https://iqbalansari.github.io/blog/2014/12/07/automatically-create-parent-directories-on-visiting-a-new-file-in-emacs/'" │ (let ((parent-directory (file-name-directory buffer-file-name))) │ (when (and (not (file-exists-p parent-directory)) │ (y-or-n-p (format "Directory %s' does not exist. Create it?" parent-directory))) │ (make-directory parent-directory t)))) │ │ (defun gcr/occur-dwim () │ "Call occur' with a mostly sane default. │ │ Attribution Oleh Krehel (abo-abo): URL http://oremacs.com/2015/01/26/occur-dwim/'" │ (interactive) │ (push (if (region-active-p) │ (buffer-substring-no-properties │ (region-beginning) │ (region-end)) │ (let ((sym (thing-at-point 'symbol))) │ (when (stringp sym) │ (regexp-quote sym)))) │ regexp-history) │ (call-interactively 'occur)) └──── Emacs lets you set up buffers that won't be re-sized or moved. That is really a nice option because sometimes you actually don't care. For me, I end up writing Emacs Lisp and working in the shell so much that it finally dawned on me that I ought to make permanent buffers for them. The height of the buffer is: • 1 row for the name of the mode • 1 row for a space between the input and the mode name • n' for everything else • there is a mininum The buffer height it set up in the functions right now and if I end up creating more then perhaps it would be time to refactor those hard codings. For now, all of that code may be easily utilized via gcr/util-cycle'. ┌──── │ (defun gcr/util-cycle () │ "Display or hide the utility buffers." │ (interactive) │ (if gcr/util-state │ (gcr/util-stop) │ (gcr/util-start))) └──── Unfill paragraph: because I should have quit doing this by hand 400 posts ago. ┌──── │ (defun sacha/unfill-paragraph (&optional region) │ "Takes a multi-line paragraph and makes it into a single line of text. │ │ ATTRIBUTION: SRC https://github.com/sachac/.emacs.d/blob/gh-pages/Sacha.org#unfill-paragraph" │ (interactive (progn │ (barf-if-buffer-read-only) │ (list t))) │ (let ((fill-column (point-max))) │ (fill-paragraph nil region))) └──── 6.2 Color Theme ─────────────── The solarized theme is the perfect theme for everything, especially bozhidar's release. It is soft and gentle yet easy to read in any situation. ┌──── │ (setq solarized-distinct-fringe-background +1) │ (setq solarized-high-contrast-mode-line +1) │ (setq solarized-use-less-bold +1) │ (setq solarized-use-more-italic nil) │ (setq solarized-emphasize-indicators nil) │ (load-theme 'solarized-dark) └──── 6.3 Windows ─────────── Menu bars are not required. Curiously, I've come to like the menu bar specifically when working with other people! ┌──── │ (menu-bar-mode +1) └──── For some reason, on OSX dialogues don't work and essentially end up locking up Emacs! Here [7] is the solution: ┌──── │ (gcr/on-osx │ (defadvice yes-or-no-p (around prevent-dialog activate) │ "Prevent yes-or-no-p from activating a dialog" │ (let ((use-dialog-box nil)) │ ad-do-it)) │ │ (defadvice y-or-n-p (around prevent-dialog-yorn activate) │ "Prevent y-or-n-p from activating a dialog" │ (let ((use-dialog-box nil)) │ ad-do-it))) └──── 6.4 Environment ─────────────── On OSX, I learned that when you start the GUI version of Emacs that it doesn't inherit the ENVIRONMENT'. This is the solution. ┌──── │ (require 'exec-path-from-shell) │ (gcr/on-osx (exec-path-from-shell-initialize)) └──── For a while I went on a quest to get the Message' buffer to include time-stamps on each entry. EmacsWiki had some decent approaches but none of them worked right for me and I didn't want to dig further. Eventually though I got tired of having to pay close attention to the minibuffer or Messages' for stuff and just started looking for GUI options. The plan is to have Messages' for most stuff and if there are alerts by any definition then I want that to be an option. First choice was todochiku [8] due to the high download count but two issues, it didn't work and it is not used by anything else. Alert [9], on the other hand, is, and also lives on Github meaning that it is maintainable. ┌──── │ (require 'alert) │ (setq alert-fade-time 10) │ (gcr/on-gui │ (gcr/on-osx │ (setq alert-default-style 'growl))) │ (setq alert-reveal-idle-time 120) └──── On Windows, you need to specify a specific shell so that Emacs can talk to other programs in the correct manner: ┌──── │ (gcr/on-windows │ (setq shell-file-name "cmdproxy.exe")) └──── Enable the super' key-space: ┌──── │ (gcr/on-osx │ (setq mac-control-modifier 'control) │ (setq mac-command-modifier 'meta) │ (setq mac-option-modifier 'super)) │ │ (gcr/on-windows │ (setq w32-lwindow-modifier 'super) │ (setq w32-rwindow-modifier 'super)) └──── 6.5 Code folding ──────────────── Code folding really isn't a hugely important function. You just use it once in a while and you notice it when you don't have it. For years I used this [10] and it is fine, but I figured I ought to stick with a more feature rich option, just to give it a try. Here are some of the other options: [11][12][13][14]. If you know org-mode, then using that style of control makes it easier to use then the built in bindings for hideshow [15], on which hideshow-org is built. After using this for a while, it came not to be the right thing for me. There is no mode hook. It failed when I wanted to bind it to something other than TAB'. So, using the built in hideshow turned out to be the best option. ┌──── │ (setq hs-hide-comments-when-hiding-all +1) │ (setq hs-isearch-open +1) │ (defun display-code-line-counts (ov) │ "Displaying overlay content in echo area or tooltip" │ (when (eq 'code (overlay-get ov 'hs)) │ (overlay-put ov 'help-echo │ (buffer-substring (overlay-start ov) │ (overlay-end ov))))) │ │ (setq hs-set-up-overlay 'display-code-line-counts) │ (defadvice goto-line (after expand-after-goto-line activate compile) │ "How do I get it to expand upon a goto-line? hideshow-expand affected block when using goto-line in a collapsed buffer." │ (save-excursion │ (hs-show-block))) └──── 6.6 Buffers ─────────── Show line numbers everywhere. [16] This may slow things down somewhere, sometime, and if it does, I will deal with it then. Well, at least this is how I used to do it. Some modes didn't handle things well and for some reason this mode wouldn't turn off. Oh well, I will manually enable it for desired modes! it will dynamically adjust the number gutter, and this irritating to have that shift occur. Fix it to 5 numbers, and if I start working with files that have 100K+ lines then I will change it. Set linum-format' via customize. ┌──── │ (global-linum-mode -1) └──── Activate syntax highlighting everywhere. [17] ┌──── │ (global-font-lock-mode 1) └──── Window navigation isn't something that I do a ton of… but I still want it to be a nice option when I use IRC and want separate windows. ace-window makes this easy: ┌──── │ (setq aw-keys '(?a ?s ?d ?f ?j ?k ?l ?\;)) └──── Visualize parentheses a certain way. [18] ┌──── │ (setq blink-matching-paren nil) │ (show-paren-mode +1) │ (setq show-paren-delay 0) │ (setq show-paren-style 'expression) └──── Don't use audible bells, use visual bells. [19] ┌──── │ (setq ring-bell-function 'ignore) │ (setq visible-bell +1) └──── This post [20] got me thinking that perhaps it was wrong of me to be happy with simply re-positioning all of my windows after their layout gets changed. Probably, I'm just a simple user and never run into this problem, or perhaps my layout is so simple that restoring it is not a big deal. That said, I've been having a nagging feeling about how exactly I plan to utilize ERC now that I've got it set up and simply avoided the topic for a while. Now is the time to address it. Reading more about winner-mode [21] [22], though, has sort of got me wondering why I never pursued something like this before now. This package /continues/ to be massively under-recognized for its simplicity and consequent power. ┌──── │ (winner-mode +1) └──── When the time is right, I'll look into Workgroups for Windows [23] or its friends. The cursor should not blink. [24] ┌──── │ (blink-cursor-mode 0) │ (gcr/on-gui │ (setq-default cursor-type 'box)) │ (setq x-stretch-cursor 1) └──── Make deleting an entire line work how you may expect [25] ┌──── │ (defadvice kill-line (around kill-line-remove-newline activate) │ (let ((kill-whole-line t)) │ ad-do-it)) └──── It is nice to have an indicator of the right column that indicates the maximum depth of the line. My favorite package is fill-column-indicator [26]. Its use shows up in almost all of the modes. While working on this build though the export to HTML included junk characters, so I had to disable it, at least in Lispy modes. My final solution to be able to use this package was to generate two Emacs configuration files, one for general use and one just for doing exports. Make it really obvious where the 80th column sits. [27] ┌──── │ (setq-default fill-column 80) └──── Something that I never missed from Idea was version control status info in the fringe, just never used it. Then when I saw it [28] in Emacs, I got curious about how it /may/ be used. So, I installed it. Curious to see how it will facilitate communicating the status of this document. Initial experiences has me thinking that it is actually much nicer than I figured, so I will enable it globally for a while. ┌──── │ (global-diff-hl-mode) └──── IntelliJ Idea is yet again to blame for being awesome; even the author of this library suffers, or rather enjoys, this phenomenon. When you make a selection of text you typically want to do it in a smart way, selecting the first logical block, then expanding logically outwards, and so on. It could mean selecting a variable, then its definition statement, and then the entire code block for example. Before now I really never had many uses for the C-u' universal argument functionality for method calls, but if you pass in a negative value before calling er/expand-region' it will have the nice feature of reversing its incremental selection. The library: [29] ┌──── │ (require 'expand-region) └──── How to jump to locations in a buffer in an easier way than by using the built in key bindings? Science… that is how. v1. This package [30] searches for the character for which you are searching at the start of a word, highlights matches, and presents you with the letter to press to jump to the match. You may also search in the middle of words. The key to using this to utilize pop-mark' to get back to where you were. v2. Navigating a buffer was never slow… until learning about ace-jump-mode [31]. The idea is so deceptively simple, and when you grok it, you will be truly shocked. The author sums it up quite succinctly ┌──── │ (autoload │ 'ace-jump-mode │ "ace-jump-mode" │ "Emacs quick move minor mode" │ t) │ (autoload │ 'ace-jump-mode-pop-mark │ "ace-jump-mode" │ "Ace jump back:-)" │ t) │ (eval-after-load "ace-jump-mode" │ '(ace-jump-mode-enable-mark-sync)) │ (define-key global-map (kbd "C-x SPC") 'ace-jump-mode-pop-mark) └──── Keep open files open across sessions. [32] You need to be really thoughtful here because desktop-mode' stores *all* buffer information. Most of the time this is exactly what you want and then you forgot about it because it /just works/ so well. The trouble comes when you reconfigure the mode and restart Emacs and those old buffer settings are re-loaded when you really wanted the new settings loaded. ┌──── │ (desktop-save-mode 1) │ (setq desktop-restore-eager 10) └──── Automatically save every buffer associated with a file [33]. This is another IntelliJ holdover. The built in auto-save in Emacs wasn't something that I needed, and this does the right thing. There is a bit more though to it, namely because the interval is only 20s I still want/need to be sure that the file is saved /before/ doing anything like running code or doing a build As such, before most operations, all buffers with files attached are saved /first/. When I switched to package' again and used el-get' to install this instead of melpa', real-auto-save' quit working. Gosh. Found [34] which gives me what I want, since I seemingly couldn't figure that out myself in the past! ┌──── │ (setq auto-save-default t) │ (setq make-backup-files nil) │ (setq auto-save-visited-file-name t) │ (setq auto-save-interval 05) │ (setq auto-save-timeout 05) └──── Bozhidar shared how to get even more default save behavior similar to Idea [35]. ┌──── │ (defadvice switch-to-buffer (before gcr/save-all-file-buffers-now activate) │ (when buffer-file-name (gcr/save-all-file-buffers))) │ (defadvice other-window (before other-window-now activate) │ (when buffer-file-name (gcr/save-all-file-buffers))) │ (defadvice windmove-up (before other-window-now activate) │ (when buffer-file-name (gcr/save-all-file-buffers))) │ (defadvice windmove-down (before other-window-now activate) │ (when buffer-file-name (gcr/save-all-file-buffers))) │ (defadvice windmove-left (before other-window-now activate) │ (when buffer-file-name (gcr/save-all-file-buffers))) │ (defadvice windmove-right (before other-window-now activate) │ (when buffer-file-name (gcr/save-all-file-buffers))) └──── Make two buffers with the same file name open distinguishable. [36] ┌──── │ (require 'uniquify) │ (setq uniquify-buffer-name-style 'forward) └──── Support transparent AES encryption of buffers. [37] See also for library paths [38] ┌──── │ (gcr/on-osx │ (add-to-list 'load-path "/usr/local/Cellar/ccrypt/1.10/share/emacs/site-lisp")) │ (gcr/on-windows │ (add-to-list 'load-path "C:\\opt\\ccrypt-1.10.cygwin-i386\\")) │ (gcr/on-gnu/linux │ (warn "Please configure ccrypt.")) │ (require 'ps-ccrypt "ps-ccrypt.el") └──── With modern VCS, backup files aren't required. [39] ┌──── │ (setq backup-inhibited 1) └──── Ban white-space at end of lines, globally. [40] ┌──── │ (add-hook 'write-file-hooks │ (lambda () │ (gcr/delete-trailing-whitespace))) └──── The world is so rich with expressivity. Although Unicode may never capture all of the worlds symbols, it comes close. [41] [42] [43] ┌──── │ (prefer-coding-system 'utf-8) │ (gcr/on-gui │ (setq x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING)) │ (gcr/on-windows │ (set-clipboard-coding-system 'utf-16le-dos))) └──── The value default-process-coding-system' seems to be set automatically, and it is worth noting here that two things need to be set namely buffer coding and process coding and that both seem to be set [44]. Emacs has a powerful buffer tracking change system. Unfortunately, I don't understand any of it. Undo should "just work". ┌──── │ (require 'undo-tree) │ (global-undo-tree-mode 1) │ (gcr/diminish 'undo-tree-mode) └──── Sometimes it is a problem when you haven't got a newline ending a file with source code before it… org-mode is one such case. Require that every file have a final newline before saving it. ┌──── │ (setq require-final-newline t) └──── Speaking of line endings just read this [45]. If I ever want to force line ending type based on file name, then that is how. For a long time I wanted auto-revert everywhere and for some reason gave up on adding it. What the heck? I am human. ┌──── │ (global-auto-revert-mode 1) └──── This [46] post suggest that wanting to "never have unindented code again" is "aggressive". Well, perhaps that is a bit strong? However, it is certainly interesting and perhaps even controversial. Nobody wants to be locked down in their editor with their code. Perhaps the bondage and discipline language user would disagree? I don't mind, in regards to editors and code at least! Using this approach doesn't prevent you from doing anything in particular other than poorly indenting code. This will be a fun experiment and I will start out with emacs-lisp and ℝ to see how it goes. Generally the experiment has gone well, and it is not it's own package, and it uses autoload so there is no more code here. Dealing with markup that uses tags is pretty easy per-mode as you do it once and you are done. In modes liks org' though you tend to have more evolutionary steps in your document so you end up wrapping things after the fact a lot. wrap-region' [47] makes this easy, fast, and intuitive. Well it lets /you/ do it, which is just as good! Thoughts: • Should mode setting be defined here? • Will try for now • Should wrap-region-remove-wrapper' be specified? • Won't for now can just undo. ┌──── │ (require 'wrap-region) │ (gcr/diminish 'wrap-region-mode) │ │ (wrap-region-add-wrapper "*" "*" nil 'org-mode) ;; bold │ (wrap-region-add-wrapper "/" "/" nil 'org-mode) ;; italic │ (wrap-region-add-wrapper "_" "_" nil 'org-mode) ;; underlined │ (wrap-region-add-wrapper "=" "=" nil 'org-mode) ;; verbatim │ (wrap-region-add-wrapper "~" "~" nil 'org-mode) ;; code │ (wrap-region-add-wrapper "+" "+" nil 'org-mode) ;; strike-through │ ;; (wrap-region-add-wrapper "«" "»" "w" 'org-mode) ;; noweb blocks └──── Usually you actually need two scratch buffers, one for Emacs lisp and one for text: ┌──── │ (let ((text-buffer (get-buffer-create "*text*"))) │ (with-current-buffer text-buffer │ (text-mode) │ (insert "Shall we play a game?") │ (beginning-of-line))) └──── A lot of times you write things that involves quoting large chunks from other documents. I'm thinking this is more spur of the moment… like in emails. However, this may occur anywhere I suppose. Perhaps coding is another place? At least when you are not doing LP it would be more likely. This [48] seems like a nice way to make it obvious when I insert quoted text: ┌──── │ (require 'boxquote) └──── The more that I use this package, the more obvious it becomes how insanely useful it is. How you move around lines in a file is configurable. My preference is that if I am on the end of a line, and I go up or down, then I want to go to the end of line on that new line. Specifically, I do not want to account for anything special about the character I am dealing with. This is what most folks would expect: ┌──── │ (setq track-eol +1) │ (setq line-move-visual nil) └──── Sometimes you want to swap two pieces of text within a buffer. This library makes it very simple to do that by selecting what you want to swap, starting the anchored transpose, and then choosing its destination. ┌──── │ (global-set-key [?\C-x ?t] 'anchored-transpose) │ (autoload 'anchored-transpose "anchored-transpose" nil t) └──── For a long while I used tabbar' [49] and found it to be quite nice. You may easily cycle through specific types of files and specific types of buffers of your choice. It is a very easy to use and nice feature. Years ago, it helped me out a lot for transitioning to Emacs. Eventually, I just no longer felt the need for it… and still I think very highly of it. For the longest time, I would only keep a handful of buffers open. It was probably because of my VIMentality. That is what everyone says, attributing everything to the editor that they are using. It was really my choice though not the editor's choice! Nonetheless, with time, I was able to leave more buffers open and got more curious about them, so I first turned to buffer-menu', and soon wanted more. How much more? I didn't know, and I still don't, but I will use ibuffer' [50] [51] to let me do it. Joking aside, purcell's approach [52] to group buffer's by their vc root directory and show their vc status. This is kind of a dream come true, that is exactly what I had wanted. Every time you need something good, purcell already has a solution for it. This workflow is nearly identical to how I use stathon [53], the only difference being that the latter knows about all files rather than file just open in the buffer. Perhaps projectile' will grow to include something that reports vc status? Let me check. projectile-vc' is pretty close! ┌──── │ (require 'ibuffer) └──── Having the buffer move up and down one line at a time is generally nice and fine (especially with a mouse). It is really unpleasant though when you get up to or down into the next page while scolling with the cursor because the entire contents of you screen just *jump* quite uncomfortably. My preference here is to keep the cursor 10 lines or so from the top or the bottom. This is a preference that cycles over the years… but I always come back to turning it on again. ┌──── │ (require 'smooth-scrolling) └──── Sometimes it is difficult to comprehend tabular data inside of a buffer, so make it easier. ┌──── │ (require 'stripe-buffer) └──── Not sure where to put this right now, but I want all buffers savd before this system exits as the default behavior. The default behavior of this system is that all buffers with files attached are always saved, especially before exiting the system. ┌──── │ (defadvice save-buffers-kill-terminal (before save-before-save-buffers-kill-terminal first activate) │ "Save all buffers before save-buffers-kill-terminal calls." │ (gcr/save-all-file-buffers)) └──── In my world, sentences end with a single space. This makes sentence navigation commands work for me. [54] ┌──── │ (setq sentence-end-double-space nil) └──── Visual-line-mode is really, really great. When it is running, I don't need to know about it. ┌──── │ (gcr/diminish 'visual-line-mode) └──── Hide-show is another sweet mode that I don't need to know is running. ┌──── │ (eval-after-load "hideshow" '(diminish 'hs-minor-mode)) └──── 6.7 Frames ────────── Make the title frame something special. ┌──── │ (gcr/on-osx (setq frame-title-format '("𝔸𝕃𝔼ℂ"))) │ (gcr/on-windows (setq frame-title-format '("ALEC"))) └──── The scroll bars are actually quite nice. Despite that, I don't actually use them, but I think that others would like them. The only problem is that the current theme doesn't color the bars (not sure if any do), so it has to be turned off. ┌──── │ (scroll-bar-mode 0) └──── The tool bars used to be not very nice, but now they are. I really do like this because it often provides useful things. Illogically, I don't like to see it. ┌──── │ (tool-bar-mode -1) └──── Let the mouse-wheel move the cursor in a sane manner. ┌──── │ (setq mouse-wheel-scroll-amount '(1 ((shift) . 1))) │ (setq mouse-wheel-progressive-speed nil) │ (setq mouse-wheel-follow-mouse +1) └──── 6.8 File-system management (GUI) ──────────────────────────────── Not quite sure where this should go yet. Finder is [55] is just fine (Fine-der?), and the curiosity is still there for an in-Emacs solution. Speedbar [56] and SrSpeedbar [57] look nice, as does [58]. The thing is though that with stuff like projectile', you really don't need to worry about hierarchical file-system navigation anymore. Instead, it is the familiarity that lingers, not the need. Lately I've been using finder' a lot to do file-system stuff. Is it time to integrate here? Not sure yet. direx' [59] also seems nice. Finally I ran into real scenario. This will sound kind of trivial, but it is valuable: I had 5-10 directories that I wanted to work with. I wasn't sure which ones I would want to inspect so I had to dig around. I ended up keeping 3-5 of them open at a time as I was comparing their contents. This really wasn't suitable for any combination of any command-line or Emacs tools. It is exactly what I would need a GUI to do, so now I am curious about if or how I would do this inside of Emacs. Is dired' an option here? No, not right now. OIC there are so many options [60]! What about eshell'? That doesn't really suit the use case, either. Just watched this [61] and it seems like a fine place to start. Just used it for 5 minutes and I can already see that it is wonderful for my use case. ┌──── │ (require 'neotree) └──── 6.9 File-system/directory management (Console) ────────────────────────────────────────────── The last file or file-system management tool that I used wast Norton Commander [62] and then Midnight Commander [63], but my usage was pretty basic. Beyond those basics, I can do even more, basic stuff, in bash'. Lately I've wanted something a little more consistent, powerful, and memorable, and that led me here. Dired is a user-interface for working with your file-system; you select files and directories and then choose what to do with them. The ability to customize what you see is included out of the box, and there are additional helper packages [64], too. You can use the usual machinery to work with the files. Highlight a region and operation selections occur for all files in that region. Commands are scheduled, and then executed, upon your command. Files can be viewed in modify or read-only mode, too. There is an idea of =mark-in files, which is to select them and perform operations on the marked files. There are helper methods for most things you can think if like directories or modified-files or whatever, meaning you can use regexen to mark whatever you like however you like. If that suits you, then don't be afraid of using the regular expression builder [65] that is built into Emacs. Bulk marked file operations include additionally copying, deleting, creating hard links to, renaming, modifying the mode, owner, and group information, changing the time-stamp, listing the marked files, compressing them, decrypting, verifying and signing, loading or byte compiling them (Lisp files). g' updates the current buffer; s' orders the listing by alpha or date-time. find-name-dired' beings the results back into Dired, which is nifty. Wdired lets you modify files directly via the UI, which is interesting. Image-Dired lets you do just that. +' creates a new directory. dired-copy-filename-as-kill' stores the list of files you have selected in the kill ring. dired-compare-directories' lets you perform all sorts of directory comparisons, a handy tool that you need once in a while but definitely do need. ┌──── │ (setq dired-listing-switches "-alh") │ (setq dired-recursive-deletes +1) │ (require 'dired-details+) │ (setq-default dired-details-hidden-string "") │ (defun gcr/dired-mode-hook () │ "Personal dired customizations." │ (local-set-key "c" 'gcr/dired-copy-filename) │ (local-set-key "]" 'gcr/dired-copy-path) │ (diff-hl-dired-mode) │ (load "dired-x") │ (turn-on-stripe-buffer-mode) │ (stripe-listify-buffer)) │ (add-hook 'dired-mode-hook 'gcr/dired-mode-hook) └──── Try to guess the target directory for operations. ┌──── │ (setq dired-dwim-target t) └──── After dabbling, something happened that really changed my mind. These three articles changed everything: [66] [67] [68]. They just made the power of Dired so obvious, and so easy to use, that it instantly because delightful to use. That was very, very cool. Even though I was really, really happy with Finder and Explorer… suddenly it just became so obvious and pleasant to use Dired. That is so wild. Key notes when executing shell commands on file selection… Substitution:  ?': 1* calls to cmd, each file a single argument  *': 1 call to cmd', selected list as argument = *""=: have the shell expand the * as a globbing wild-card • Not sure what this means Synchronicity:  …': by default commands are called synchronously  &': execute in parallel  ;': execute sequentially, asynchronously  ;&': execute in parallel, asynchronously Key notes on working with files in multiple directories… use the following: Use find' just like you would at the command line and all of the results show up in a single Dired buffer that you may work with just like you would any other file appearing in a Dired buffer. The abstraction here becomes so obvious, you may ask yourself why you never considered such a thing /before/ now (as I did): ┌──── │ (require 'find-dired) │ (setq find-ls-option '("-print0 | xargs -0 ls -ld" . "-ld")) └──── Noting that: find-dired': is the general use case find-name-dired': is for simple, single string cases And if you want to use the faster Elisp version, that uses lisp regex, use: find-lisp-find-dired': for anything find-lisp-find-dired-subdirectories': for only directories Key notes on working with editable buffers… As the author notes, you probably already instinctually knew what is possible. After reading his brief and concise exposition, it would be hard /not/ to intuit what is possible! The options are big if you make a writable file buffer. Think about using multiple cursors. Done? Well, that is a no-brainer. Once you grok multiple cursors just find-dired' what you need and then do what you need to do to it. Very cool. dired-toggle-read-only, C-x C-q': cycle between dired-mode and wdired-mode wdired-finish-edit, C-c C-c': commit your changes wdired-abort-changes, C-c ESC': revert your changes ┌──── │ (require 'wdired) │ (setq wdired-allow-to-change-permissions t) │ (setq wdired-allow-to-redirect-links t) │ (setq wdired-use-interactive-rename +1) │ (setq wdired-confirm-overwrite +1) │ (setq wdired-use-dired-vertical-movement 'sometimes) └──── Today I just learned about image-dired', why didn't I think to ask before now? When you selected a bunch of files or directories, you /may/ want to communicate somewhere your selection somehow. The simplest way to do this is to utilize dired-copy-filename-as-kill'. What a nice idea, and its default binding is w'. Since I started using a menu bar again, and wanting to get Imenu really exercised, Dired in Imenu seems like an obvious choice. ┌──── │ (require 'dired-imenu) └──── 6.10 Save history of all things ─────────────────────────────── See: [69] [70] [71] It is nice to have commands and their history saved so that every time you get back to work, you can just re-run stuff as you need it. It isn't a radical feature, it is just part of a good user experience. This file keeps track of everything that savehist' stores for us and doesn't need to be version controlled so it is checked as a real file. The file that savehist' stores its stuff in is not under version control. The check for the file may no longer be required. Savehist used to store its history in ~/.emacs.d/savehist. I think I copied that from emacs-fu. Recently their API updated. My code to store this setting in that file broke. When it broke Savehist just saved its stuff in the default file. That works. I didn't even notice it. That is fine with me. I am leaving it alone. I kept this check code in place to check that the default history file is there. ┌──── │ (defconst gcr/savehist-file-store "~/.emacs.d/history") │ (defun gcr/warn-savehist-file-store () │ "Warn of savehist misconfiguration." │ (interactive) │ (unless (gcr/file-exists-not-symlink gcr/savehist-file-store) │ (warn "Can't seem to find a savehist store file where it was expected at: %S. Savehist should continue to function normally; but your history may be lost." │ gcr/savehist-file-store))) └──── savehist' configuration follows. ┌──── │ (gcr/warn-savehist-file-store) │ (setq savehist-save-minibuffer-history 1) │ (setq savehist-additional-variables │ '(kill-ring │ search-ring │ regexp-search-ring)) │ (savehist-mode +1) └──── 6.11 Spell-checking ─────────────────── See: [72] [73] [74] [75] There are two ways to spell-check: run-at-a-time or interactive. Both delegate the actual checking to aspell, ispell, and hunspell. Both styles are quite nice options, and flyspell will even integrated with compilers to help report those kinds of errors to you, too, but my personal preference for now is run-at-a-time. The taxpayers didn't pay so much to make flyspell have to do all the hard work for me. aspell is there most UNI*, running ispell' from Emacs just does the right thing. Even after reading this later, I agree with it despite the fact that I constantly wax and wane between wanting to use it and finding something /better/ despite having no criteria by which to truly judge in the first place. The aspell' personal directionary is version controlled. These Aspell artifacts are valuable. Treat them appropriately. Don't place junk in them. Review them periodically. Weed out bad entries. ┌──── │ (defconst gcr/aspell-personal-dictionary "~/.aspell.en.pws") │ (defun gcr/warn-aspell-personal-dictionary () │ "Warn of aspell misconfiguration: personal dictionary." │ (interactive) │ (unless (gcr/file-exists-is-symlink gcr/aspell-personal-dictionary) │ (warn │ "Can't seem to find an aspell personal dictionary where it was expected at: %S. aspell should continue to function normally; but your personal dictionary will not be used." │ gcr/aspell-personal-dictionary))) │ (gcr/warn-aspell-personal-dictionary) └──── So is the personal replacement dictionary. This is a copy and paste of the previous section. It is obviously a candidate for cleanup. ┌──── │ (defconst gcr/aspell-personal-replacement-dictionary "~/.aspell.en.prepl") │ (defun gcr/warn-aspell-personal-replacement-dictionary () │ "Warn of aspell misconfiguration: personal replacement dictionary." │ (interactive) │ (unless (gcr/file-exists-is-symlink gcr/aspell-personal-replacement-dictionary) │ (warn │ "Can't seem to find an aspell personal replacement dictionary where it was expected at: %S. aspell should continue to function normally; but your personal replacement dictionary will not be used." │ gcr/aspell-personal-replacement-dictionary))) │ (gcr/warn-aspell-personal-replacement-dictionary) └──── 6.12 Syntax checking ──────────────────── It is a great feature. Flyspell never interested me though because of so many negative reports and it just didn't seem that important. Well, that was before breaking this document for the N^{th} time! There is a need, and Flycheck [76] seems to be the best of the best out there. ┌──── │ (require 'flycheck) │ (add-hook 'after-init-hook #'global-flycheck-mode) │ (gcr/diminish 'flycheck-mode) └──── 6.13 Templating ─────────────── See: [77] Code completion is nice to have; but the second you install it and learn how to use it, you will never find the need to again. Accept it and move on. yas' snippets directory is not version controlled. ┌──── │ (require 'yasnippet) └──── Remaining configuration follows. ┌──── │ (yas-global-mode 1) │ (gcr/diminish 'yas-minor-mode) └──── yas' shouldn't use TAB'. ┌──── │ (defun gcr/yas-minor-mode-hook () │ "Personal customizations." │ (define-key yas-minor-mode-map (kbd "") nil) │ (define-key yas-minor-mode-map (kbd "TAB") nil) │ (define-key yas-minor-mode-map (kbd "s-4") 'yas-expand)) │ │ (add-hook 'yas-minor-mode-hook 'gcr/yas-minor-mode-hook) └──── 6.14 White-space management ─────────────────────────── See: [78] Do you need to see tabs and other control characters? Usually, yes. ┌──── │ (require 'whitespace) │ (setq whitespace-style '(trailing lines tab-mark)) │ (setq whitespace-line-column 80) │ (global-whitespace-mode 1) │ (gcr/diminish 'global-whitespace-mode) │ (gcr/diminish 'whitespace-mode) └──── 6.15 Mark and Region ──────────────────── When you start typing and text is selected, replace it with what you are typing, or pasting, or whatever. [79] ┌──── │ (delete-selection-mode 1) └──── 6.16 Modeline ───────────── When you load modes, most of them show up in the modeline. After you read their name a few thousand times, you eventually quite forgetting that you loaded them and need a diminished reminder. [80] ┌──── │ (require 'diminish) └──── The modeline is capable of so many things. Though I use it for few, I value it greatly. Even the generic, optional options [81] are nice. Show the file size. ┌──── │ (size-indication-mode) └──── It is nice to see the column number, if you are counting columns (not calories). ┌──── │ (column-number-mode 1) └──── Humans posess the technology to enable to track time and date in a watchpiece. For fear of damaging either the watchpiece or the computer itself, I quite wearing watches long ago. That was a mistake. Put on a time piece and turn off date and time status on the host OS and inside of Emacs. This source block is kept for reference, and excluded from the generated configuration. ┌──── │ (setq display-time-format "%R %y-%m-%d") │ (display-time-mode +1) └──── Over time you start to, as which everything else in Emacs, think about configuring it "better". Simple things like the file state indicator [82] is one of the first to jump out at you. In my case I've made some nice changes via the built-in mechanisms. Powerline [83] really got me thinking though just because it is so stunning with the use of XPM [84]. Reading through it though, it would require some real digging in, and the documentation doesn't say much and I wasn't sure that I wanted to pursue that much right now. Simple mode line [85] says all the right things, I like their documentation and am not sure whether or not it knows the right things to highlight, or not. How does it know? Clearly there are many ideas [86] on how to customize the modeline. How may we be sure that they are doing it right and displaying everything that mode expects them to possibly be displaying? Like most things it is just trust, and verify. For now it is easier to stick with the built in, and grow it organically. Perhaps more importantly, I /do/ like the built-in modeline style. 6.17 Speed ────────── As of <2014-07-05 Sat>, there is, as one would expect, quite a focus on speeding up Emacs. What is the definition of speeding it up? Well, that depends. Like any UX designer knows, it is all subjective. Is a lazy-load to make startup feel fast making it faster? It depends. What struck me is the trend for the last few years to autoload' basically everything in packages. That is a curious step because I prefer require' to make it obvious what we are doing. Either way, speed matters and all of these topics got me wanting at least to know what is going on with Emacs in terms of speed… by some measure. Emacs Start Up Profiler (ESUP) [87] does just what it says, and I use it here. For now I do not want to record startup times becase I've got no question that I want to be answered yet. As of <2014-07-05 Sat> the startup is 3.181sec'. ┌──── │ (autoload 'esup "esup" "Emacs Start Up Profiler." nil) └──── 6.18 Minibuffer ─────────────── You will want to configure this at some point. Make it easier to answer questions. ┌──── │ (fset 'yes-or-no-p 'y-or-n-p) └──── It often displays so much information, even temporarily, that it is nice to give it some room to breath. [88] ┌──── │ (setq resize-mini-windows +1) │ (setq max-mini-window-height 0.33) └──── Allow recursive commands-in-commands show help me keep track of the levels of recursion. ┌──── │ (setq enable-recursive-minibuffers t) │ (minibuffer-depth-indicate-mode 1) └──── 6.19 Searching / Finding / Replacing [89] [90] ────────────────────────────────────────────── 6.19.1 Searching ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ Perhaps an odd topic, but how you handle spaces when performing an interactive search is a choice: ┌──── │ (setq isearch-lax-whitespace +1) │ (setq isearch-regexp-lax-whitespace +1) └──── Make searches case-insensitive. ┌──── │ (setq-default case-fold-search +1) └──── 6.19.2 Finding ╌╌╌╌╌╌╌╌╌╌╌╌╌╌ There are many ways to easily find what you need, for a command, for a file, and this mode seems to be a quite nice way. Something I had been curious about but forgotten and stumbled upon again was vertical ido listing, and I added that back to see how it goes. My initial reaction was that I had wanted this all along, though the transition from looking left-right to top-down was a little unsettling. ┌──── │ (require 'ido) │ (require 'flx-ido) │ (ido-mode 1) │ (require 'ido-hacks nil +1) │ (require 'ido-ubiquitous) │ (ido-ubiquitous-mode +1) │ (setq ido-create-new-buffer 'always) │ (flx-ido-mode +1) │ (setq ido-use-faces nil) │ (require 'ido-vertical-mode) │ (ido-vertical-mode +1) │ (setq ido-vertical-define-keys 'C-n-C-p-up-down-left-right) └──── 6.19.3 Replacing ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ When I use search and replace I just keep doing it until the buffer loops around. Replacing stops so that works fine. Searching loops around continually. I have to pay attention to that looping. I am doing it wrong. Anzu is doing it right by showing you what is happening. ┌──── │ (require 'anzu) │ (global-anzu-mode +1) │ (global-set-key (kbd "M-%") 'anzu-query-replace) │ (global-set-key (kbd "C-M-%") 'anzu-query-replace-regexp) │ (setq anzu-mode-lighter "") │ (setq anzu-deactivate-region t) │ (setq anzu-search-threshold 1000) │ (setq anzu-replace-to-string-separator " => ") └──── anzu-replace-at-cursor-thing' is interesting. I might do exactly the same thing with Multiple Cursors instead. It is great having options. Solarized already has [support] for Anzu. I don't like it. I could only configure it using Customize. [support] https://github.com/bbatsov/solarized-emacs/blob/master/solarized.el#L526 6.20 Sudo ───────── Most of the time I work inside Emacs. I never liked how it handled opening up files owned by root. I never did anything about it. Instead I just used VI. Last week I was editing a HOSTS file. I wanted to double check the domain name I had entered. I didn't know how in VI. I did know how in Emacs. VI is great and I'll never un-learn the five commands that I learned twenty years ago. I will always use it on freshly set up systems. I will always use it on systems without my personal Emacs configuration. It will always be a valuable tool for me. On systems where I've got Emacs running all of the time it is stupid not to use it for files that require sudo. A while ago I made that choice and said that I would change when it makes sense. Now it makes sense. I tried this [91] out. When I typed in the root password and hit enter I got the error ┌──── │ E RET is undefined └──── It looks like "E" got defined as a prefix key? My first reaction was "oh well". I don't remember that. I am not very interested in fixing it. That means that it is time for some carbohydrates. After searching I found only two posts. The second one [92] was the best. It explained how to find out what key-bindings could be activated given the key(s) that you have already typed. *WOW*. That is a /big deal/. Type your keys and hit C-h'. Of course you do. With that tip it got real clear real fast where the error lie: ┌──── │ │ Major Mode Bindings Starting With E: │ key binding │ --- ------- │ │ E S Prefix Command │ │ E S C Prefix Command │ │ E S C SPC Prefix Command │ │ E S C SPC y gcr/paste-from-x-clipboard │ │ │ Global Bindings Starting With E: │ key binding │ --- ------- └──── In other words, the error occurred between the chair and the keyboard. Of course it did. ┌──── │ (gcr/on-gnu/linux-or-osx │ (defadvice ido-find-file (after find-file-sudo activate) │ "Find file as root if necessary. │ │ Attribution: SRC http://emacsredux.com/blog/2013/04/21/edit-files-as-root/'" │ (unless (and buffer-file-name │ (file-writable-p buffer-file-name)) │ (find-alternate-file (concat "/sudo:root@localhost:" buffer-file-name))))) └──── 6.21 Popups ─────────── If possible, use a better pop-up [93] . Pos-tip should help [94]. Have mixed feelings about this. First, glad it is here, and a lot of packages do use it. Eventually I'll need to set up a larger font. ┌──── │ (require 'pos-tip) │ (gcr/on-windows │ (ignore-errors │ (pos-tip-w32-max-width-height))) └──── My desire was to have pos-tip' use the current theme values, but I couldn't figure out how and the folks online weren't quite sure either… it wasn't worth pursuing and I copied the values straight out of the theme itself. [This] was added to the theme config, but I prefer non-bold colors, so I will leave this for now. ┌──── │ (setq pos-tip-foreground-color "#073642") │ (setq pos-tip-background-color "#839496") └──── [This] https://github.com/bbatsov/solarized-emacs/blob/master/solarized.el#L1989 6.22 Intellisense (Auto Completion) [95] ──────────────────────────────────────── Can you thrive and profit without auto-completion? Surely. The feature is kind of a comfort blanket for most of us; you will never fail to build a system without it (unless you are using Java, then you need IntelliJ). Still it is quite nice to have popup documentation. Still wanting a nice documentation popup, I think that yet again Purcell and friends make our lives easier. Thus far, auto-complete has worked fine. More than a few blog-posts do mention company-mode [96], so I read up on it. It seems quite nice, but right now I haven't got a reason to explore it further though. This package is not happy running under Org Mode, FYI, for some reason. Still having some mixed feelings about what engine to use to display the popups. Popup itself is quite easy for me to read since it uses the same font as everything else. That alone makes it perfect. Still, the idea of having real popups is intriguing. Either way, both do work, so I will customize as needed. Until I customize the pos-tip font to make it bigger, though, I will stick with the old-fashioned style. ┌──── │ (require 'fuzzy) │ (require 'auto-complete) │ (require 'auto-complete-config) │ (setq ac-quick-help-prefer-pos-tip nil) │ (ac-config-default) │ (setq ac-auto-start nil) │ (ac-set-trigger-key "TAB") │ (gcr/diminish 'auto-complete-mode) └──── Auto-completion for .-separated words [97] seems like a good idea, so I will put it here and not worry too much about what header this lives in. The source explains how to use this feature… it must be specified what is allowed per-mode • which makes sense. ┌──── │ (require 'auto-complete-chunk) └──── 6.23 Symbolic Expression Management [98] ──────────────────────────────────────── There are a lot of nice options [99] [100] [101] [102] [103]. For the longest time, paredit' was all that I used, but then I started using Emacs for everyone else besides Lisp and was kind of stymied not having great expression management tools. Smartparens seems to have emerged as king, so here it sits. While I was setting up the new configuration I set this up last… that was a major mistake. After using a good symbolic expression management tool, you quickly forget the nightmare of having to keep expressions balanced yourself. Sure we did fine with VI… but it is so nice to have the tool do it for you. Remember what Olin Shivers said? I object to doing things that computers can do. You get a lot of niceties that you would expect like balanced brackets and since there is a strict mode it acts just like Paredit. Additionally you may wrap selections with pairs, auto-escape strings that occur within other strings, and showing matching pairs (of any supported form). sp-show-pair-from-inside' is kind of interesting. How it works is that normally when your cursor is to the right of a bracket, then the entire expression is highlighted. My assumption is to make it easy for you to see the scope of the s-exp. When you move forward, to the right of that opening bracket, then that highlight goes away. When you set this flag to non-nil, you get a different behavior where just the bracket is highlighted. Not sure how this would help, but still it is kind of interesting to me because it keep your focus. My use case is that you find an s-exp that you want to edit and start doing it, and in that case I wouldn't use this flag. However, say you had wanted to edit and moved the cursor one char forward and were interrupted. Perhaps you would this kind of highlight so when you come back there is still some indicator. From a user-perspective, it just seemed interesting. ┌──── │ (require 'smartparens-config) │ (show-smartparens-global-mode +1) │ (gcr/diminish 'smartparens-mode) │ (setq sp-show-pair-from-inside nil) └──── Recently I learned of [104] Paxedit. "One command /just works/ *everywhere*!". Good to know. Once you get on-board with structural editing, you do, kind of want it /everywhere/. 6.24 Evaluation ─────────────── ┌──── │ (setq-default eval-expression-print-level nil) └──── Allow these commands: ┌──── │ (put 'upcase-region 'disabled nil) │ (put 'downcase-region 'disabled nil) │ (put 'narrow-to-region 'disabled nil) └──── 6.25 Version control / Git ────────────────────────── All version control systems basically work fine in Emacs version control (VC) abstraction layer, and I like it a lot. What made me focus on Git and how I work with it though was two things: 1-I use that for hours and hours at work and home and 2-I had been using a standalone Git UI and I felt like it was kind of stupid not to use something built into Emacs. This will require further research. One thing that I did find that I wanted though was that despite having set auto save to occur quite frequently, it was still possible to initiate a VC action without the buffering being saved. My solution for that is that before *every* VC action, at least the current buffer must be saved. This is OK because I believe that VC actions only occur on a per-file basis, versus command line VC operations. Then I added he same thing for diff. ┌──── │ (defadvice vc-next-action (before save-before-vc first activate) │ "Save all buffers before any VC next-action function calls." │ (gcr/save-all-file-buffers)) │ │ (defadvice vc-diff (before save-before-vc-diff first activate) │ "Save all buffers before vc-diff calls." │ (gcr/save-all-file-buffers)) │ │ (defadvice vc-ediff (before save-before-vc-ediff first activate) │ "Save all buffers before vc-ediff calls." │ (gcr/save-all-file-buffers)) │ │ (defadvice vc-revert (before save-before-vc-revert first activate) │ "Save all buffers before vc-revert calls." │ (gcr/save-all-file-buffers)) └──── The log edit buffer is only used in VC mode I think, and needs to some configuration. ┌──── │ (defun gcr/log-edit-mode-hook () │ "Personal mode bindings for log-edit-mode." │ (gcr/untabify-buffer-hook) │ (gcr/disable-tabs) │ (fci-mode)) │ │ (add-hook 'log-edit-mode-hook 'gcr/log-edit-mode-hook) │ │ (defun gcr/log-edit-mode-hook-local-bindings () │ "Helpful bindings for log edit buffers." │ (local-set-key (kbd "C-;") 'log-edit-done)) │ │ (add-hook 'log-edit-mode-hook 'gcr/log-edit-mode-hook-local-bindings) └──── magit' also should have a similar configuration. Magit is very important. Eventually it will go under its own heading. Save every buffer with a file attached before starting Magit. This is how it is done with VC up above. ┌──── │ (defadvice magit-status (before save-before-magit first activate) │ "Save all buffers before using Magit." │ (gcr/save-all-file-buffers)) └──── Make sure Magit knows that I read the warning. It wasn't instructions. ┌──── │ (setq magit-last-seen-setup-instructions "1.4.0") └──── ┌──── │ (defun gcr/git-commit-commit () │ "Allow commit message to save before committing." │ (interactive) │ (save-buffer) │ (git-commit-commit)) │ │ (defun gcr/git-commit-mode-hook () │ "Personal customizations." │ (local-set-key (kbd "C-;") 'gcr/git-commit-commit)) │ │ (add-hook 'git-commit-mode-hook 'gcr/git-commit-mode-hook) └──── The commit messages are not formatted for all vc providers, so just don't use the default message at all for [now]. ┌──── │ (eval-after-load 'log-edit │ '(remove-hook 'log-edit-hook 'log-edit-insert-message-template)) └──── This current configuration that kind of maximizes speed, doesn't account for multiple changes that need to be committed. Learning more about magit' by using it I thought that I should change the current vc' workflow over to use magit' for committing. Comparing vc' and magit', I decided that the current approach is still fine because it works so quickly, because I mostly change single files at a time, and when I don't, magit' is so fast and intuitive, that there is no need to port over my mappings or something into magit'. At least, that is my current plan for now. Magit is a really, really nice tool. It is pretty clear to me though that my assessment of it says more about my ability to use Emacs than it says about magit'. Only after skinning my knuckles on Emacs, in a more painful way, am I finally able to appreciate stuff like this. Git ignore files are just text files. ┌──── │ (add-to-list 'auto-mode-alist '(".gitignore$" . text-mode)) └──── Diminish Magit's auto-revert mode. ┌──── │ (eval-after-load "magit" '(diminish 'magit-auto-revert-mode)) └──── [now] http://debbugs.gnu.org/cgi/bugreport.cgi?bug%3D18954 6.26 Command execution helper [105] ─────────────────────────────────── When I call commands, I usually end up running the same commands over and over. There are of course key-bindings to deal with this, and also command history. What I really prefer though is just being able to type an abbreviation for the command to access it, like org-html-export-to-html' for example. Smex makes it happen. ┌──── │ (require 'smex) │ (smex-initialize) └──── Tell magit' about git working copies that projectile' knows about [106]. ┌──── │ (eval-after-load "projectile" │ '(progn (setq magit-repo-dirs (mapcar (lambda (dir) │ (substring dir 0 -1)) │ (remove-if-not (lambda (project) │ (file-directory-p (concat project "/.git/"))) │ (projectile-relevant-known-projects))) │ │ magit-repo-dirs-depth 1))) └──── 6.27 Rectangle / Cursors [107] [108] ──────────────────────────────────── Once in a very long while I have the need to modify rectangles. Only once in a while because one may use the key recorder to do most of the same work. There are a few options [109], and that bothers me, so I didn't choose any of them. This version of Emacs comes with an edit mode. Working here thought got me thinking about other folks perspectives, and I ended up here [110]. This is a strangely intriguing feature. It is quite versatile as long as you have got a mental model for things. The difference is that if you are OK with key macros, imagine that multiple-cursors is kind of a way to use keyboard macros while making it very visible and dynamic and also using the cursor location along with that interactivity. ┌──── │ (require 'multiple-cursors) └──── 6.28 Font ───────── The studies cited above indicate that the two major factors that contribute to readability of a document are contrast and font-face. Sayre's law [111] however demands that any number of other things are critical to how your IDE looks! That is OK. This section captures some of the basics to getting the system looking how I like it. This is a san-serif, portable, massively Unicode supported font. You may easily change the font size using gcr/text-scale-increase' and gcr/text-scale-decrease'; font information appears in the *Messages*' buffer and also the mini-buffer. The font size will be the same everywhere; as it is easier to work between graphic and console mode with that consistency. You may bypass that using the built in functions. The color theme seems to provide excellent contrast, though I can't decipher what the creator is actually saying about them. For a while I went between the light and dark solarized theme, and finally accepted that I'm happy with light for documents and dark for programs. That is not scientific, and I'm OK with that. Fortunately you can theme per buffer. Unfortunately, it doesn't quite work perfectly. It wasn't a big deal until it broke org's export to HTML. Since I needed that especially for right now, I decided to stick with the dark theme, as it is more familiar. As of this writing there are no less than 3 packages that provide solarized. After reading their documentation quite closely it came down something relatively simple: face support. Trying to set up help pop-ups to look decent I noticed that auto-complete' and popup' looked horrible. Reading through the different versions, there was only one [112] package that provided so many faces that I needed and the others did not so the decision was easy. Sometimes you don't like how a characters looks, or don't have access to Unicode. In such cases, pretty-mode displays substitutions for certain occurrences of flagged strings, for example replacing the world lambda' with the symbol λ. Based upon the above research, use the DejaVu font family. ┌──── │ (defconst gcr/font-base "DejaVu Sans Mono" "The preferred font name.") └──── Months and months and months after that delightful research I was stunned to learn of [113] the [unicode-fonts]. It seems that it will make all of my Unicode dreams come true. Can't wait to fall asleep now! One thing I am actualy really excited about is to be able to use Emacs for Tamil and Sanskrit. ┌──── │ (require 'unicode-fonts) │ (unicode-fonts-setup) └──── Here are the Unicode fonts that I am using, with the specific download links that I used to install on my system: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Name Version URL Comments ──────────────────────────────────────────────────────── [DejaVu] 2.43 [.] Modern classic [Symbola] 7.17 [.] Neat [Quivira] 4.0 [.] Amazing [Noto] ? [1] [2] Has morese code, and more ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ To test it I ran view-hello-file' and M-x list-charset-chars RET unicode-bmp RET'. It may not be the most scientific approach, but it is clear that there is more character support then before! All of the Tamil letters are there, though I wasn't able to download the font apparently OSX has font support built it. Perhaps humorously, finally we have support for 💩. Set a font size that may easily be read, on $\frac{1}{2}$ of a high resolution screen, 80 columns wide. ┌──── │ (defvar gcr/font-size 10 "The preferred font size.") │ (gcr/on-osx (setq gcr/font-size 17)) │ (gcr/on-windows (setq gcr/font-size 13)) └──── Convert common ASCII values into Unicode representations /for display only/. ┌──── │ (require 'pretty-mode) └──── When it is /typing time/, do not show the mouse cursor. Be at ease, it will return once you move it again. The mouse is a /good thing/, but it doesn't mean that you have to stare at it all of the time! ┌──── │ (setq make-pointer-invisible +1) └──── Load font utilities when on a GUI. ┌──── │ (gcr/on-gui │ «font-decision» │ (defun gcr/font-ok-p () │ "Is the configured font valid?" │ (interactive) │ (member gcr/font-base (font-family-list))) │ (defun gcr/font-name () │ "Compute the font name and size string." │ (interactive) │ (let* ((size (number-to-string gcr/font-size)) │ (name (concat gcr/font-base "-" size))) │ name)) │ (defun gcr/update-font () │ "Updates the current font given configuration values." │ (interactive) │ (if (gcr/font-ok-p) │ (progn │ (message "Setting font to: %s" (gcr/font-name)) │ (set-default-font (gcr/font-name))) │ (message (concat "Your preferred font is not available: " gcr/font-base)))) │ (defun gcr/text-scale-increase () │ "Increase font size" │ (interactive) │ (setq gcr/font-size (+ gcr/font-size 1)) │ (gcr/update-font)) │ (defun gcr/text-scale-decrease () │ "Reduce font size." │ (interactive) │ (when (> gcr/font-size 1) │ (setq gcr/font-size (- gcr/font-size 1)) │ (gcr/update-font))) │ (gcr/update-font)) └──── [unicode-fonts] https://github.com/rolandwalker/unicode-fonts [DejaVu] http://sourceforge.net/projects/dejavu/files/dejavu/2.34/dejavu-fonts-ttf-2.34.tar.bz2 [.] http://sourceforge.net/projects/dejavu/files/dejavu/2.34/dejavu-fonts-ttf-2.34.tar.bz2 [Symbola] http://users.teilar.gr/~g1951d/ [.] http://users.teilar.gr/~g1951d/Symbola.zip [Quivira] http://www.quivira-font.com/ [.] http://www.quivira-font.com/files/Quivira.otf [Noto] https://code.google.com/p/noto/ [1] http://noto.googlecode.com/git/fonts/individual/hinted/NotoSans-Regular.ttc [2] http://noto.googlecode.com/git/fonts/individual/unhinted/NotoSansSymbols-Regular.ttf 6.29 Project management [114] ───────────────────────────── Not everyone likes projects, but I do. There is no perfect middle ground though, that is until this library came along. It is such a joy to use. Somehow I forgot how much I liked it because it is so easy to just use ido-find-file' for things. After reading a blog post, I revisited the difference between that and projectile-find-file' … well the latter has its place as it makes it much simpler only to deal with files that are known to be project files. ┌──── │ (projectile-global-mode 1) │ (gcr/diminish 'projectile-mode) └──── 6.30 Emacs Speaks Statistics (ESS) [115] [116] [117] [118] [119] [120] ────────────────────────────────────────────────────────────────────── This section takes about 15 seconds to tangle. Get ESS' loaded before doing anything with it in here or out there. ┌──── │ (require 'ess-site) └──── For a minimalist release history, read the news file [121]. For a brief, brief overview and release history, read the readme [122]. For a comprehensive overview, read the manual [123]. In it: • 𝕊 refers to any language in the family. • ℝ is what I'm interested in. • First 2.5 pages do some nice expectation-setting. • Generally seems like a highly rich development environment with support for editing, debugging, and support with everything that you would expect from the best of Emacs. • Manual covers most requested variables for configuring, but the customize facility covers more, and mentions that either way you should avoid doing so until you have used ESS' for a while. • Check that ess' is installed with a call to ess-version'. ┌──── │ (defconst gcr/ess-version "14.11") │ │ (defun gcr/warn-ess-version () │ "Warn of ess misconfiguration." │ (interactive) │ (when (not (version= ess-version gcr/ess-version)) │ (warn "Insufficient ess-mode requirements. Expected %S. Found: %S " gcr/ess-version ess-version))) │ (gcr/warn-ess-version) └──── ℝ first notes: • ℝ will start ℝ via Emacs' • Multiple ESS' processes may run simultaneously, and may be selected by a specific language via their buffer name that has a number appended, or may be accessed via a menu using ess-request-a-process'. • ESS' works transparently on remote machines using TRAMP' to manage a remote ℝ instance. An example is provided for Amazon. Means exist for supporting remote graphical displays or redirecting to a file. Excellent support seems to exist to quite flexibly support unexpected things like starting an ESS' supported program in a plain old shell and being able to convert it to an ESS' supported buffer. Various user interaction stuff: • Return sends the input from wherever you hit return, nice. • M-{' and M-}' cycle through commands you ran • M-h' select a whole "paragraph", a block in their terms • C-x [' moves through the previous ESS sessions, C-x ]' forward. • C-c C-p' and C-c C-n' cycle through previous commands. • How is this different than the other one? • C-c RET' copies an old command to the prompt without running it • Great idea • Keep your session transcript pruned • ess-transcript-clean-region' removes non-commands from a transcript for you • Previous command look-up can be done by completion via comint-*-matching'. • M-p' and M-n' seem to work just fine though. • Previous command execution, by name, offset, or just the last one, are by !' • This feature is actually quite rich and a real regexen style system. Always show eldoc for ℝ stuff, everywhere it may. ┌──── │ (setq ess-eldoc-show-on-symbol t) └──── Various session interaction stuff • Show objects in the work-space: C-c C-x' • Search for what libraries are available to the work-space: C-c C-s' • Load file with source: C-c C-l' • Visit errors: =C-c '= and =C-x '= • Show help on an object: C-c C-v' • Quit: C-c C-q' • Abort: C-c C-c' • Switch between the console and the most recent file buffer: C-c C-z' Sending code to the ESS process • ess-eval-region-or-line-and-step': Eval the region, or the line, move to next line • C-M-x': Eval the current region, function, or paragraph • C-c C-c': Do that and then go to the next line • C-c C-j': Eval the current line • C-c M-j': Eval line and jump to the console • C-c C-f': Eval the currently selected function • C-c M-f': Eval the currently selected function and jump to the console • C-c C-r': Eval the region • C-c M-r': Eval the region and jump to the console • C-c C-b': Eval the buffer • C-c M-b': Eval the buffer and jump to the console • You can do all this stuff from transcript files, too. • My thought is that I never, ever will and if I do need to, I'm looking up the commands again as I don't want to make a habit of doing that kind of thing (running old transcripts). Editing objects and functions: • C-c C-e C-d': Edit the current object • C-c C-l': Load source file into the ESS process • TAB' Indents/re-formats or completes code. • M-;': Correctly indents the current comment Help mode inside of ESS: • C-c C-v': ess-display-help-on-object': Get help on anything • ?': Show commands available in help mode • h': Show help for a different object. Currently focused object defaults. • n' and p': Cycle through sections • l': Eval the current line in the console; usually sample code. • r': Eval current region, too • q': Quit out of that buffer • k': Kill that buffer • x': Kill that buffer and return to ESS • i': Get info on a package • v': Show vignettes • w': Show current help page in browser Completion: • TAB': Complete anything • M-?': Show completions available • ess-resynch': Refreshes the completion cache *ess-tracebug* start ┌──── │ (setq ess-use-tracebug t) └──── For all ess-tracebug' stuff, the map prefix is C-c C-t' <2014-11-11 Tue> The documentation for ess-tracebug-help' provides all of this documentation that I copied from the website into here. Someday I should clean this up! Breakpoints ess-dev-map': b ess-bp-set': Set BP (repeat to cycle BP type) B ess-bp-set-conditional': Set conditional BP k ess-bp-kill': Kill BP K ess-bp-kill-all': Kill all BPs o ess-bp-toggle-state': Toggle BP state l ess-bp-set-logger': Set logger BP n ess-bp-next': Goto next BP p ess-bp-previous': Goto previous BP Note: C-' prefixed equivalents are also defined Debugging ess-dev-map':  ess-show-traceback' (also on C-c ): Show traceback ~ ess-show-call-stack' (also on C-c ~): Show callstack e ess-debug-toggle-error-action': Toggle error action (repeat to cycle) d ess-debug-flag-for-debugging': Flag for debugging u ess-debug-unflag-for-debugging': Unflag for debugging w ess-watch': Watch window Note: C-' prefixed equivalents are also defined) Interactive Debugging ess-debug-minor-mode-map': M-C ess-debug-command-continue': Continue M-C-C ess-debug-command-continue-multi': Continue multi M-N ess-debug-command-next': Next step M-C-N ess-debug-command-next-multi': Next step multi M-U ess-debug-command-up': Up frame M-Q ess-debug-command-quit': Quit debugging Navigation to errors (general Emacs functionality): C-x ', =M-g n: next-error' M-g p': previous-error' *ess-tracebug* stop • Be sure to specify this per-project. ┌──── │ (setq ess-tracebug-search-path '()) └──── • Make error navigation simpler ┌──── │ (define-key compilation-minor-mode-map [(?n)] 'next-error-no-select) │ (define-key compilation-minor-mode-map [(?p)] 'previous-error-no-select) └──── • The font size for watched variables. ┌──── │ (setq ess-watch-scale-amount -1) └──── Data viewing: • *Never* rely upon on the REPL for data viewing • Will mix up exploratory code with data • Can't easily distinguish between code and data • Distracting you • Breaking your flow • Sometimes • You end up somewhere • And the ess' buffer cursor is at the top! • No problem, call ess-switch-to-end-of-ESS' • Make it easier to know what object values are. • ess-describe-object-at-point' ┌──── │ (setq ess-describe-at-point-method 'tooltip) └──── • Visualize just about anything. • ess-R-object-popup' ┌──── │ (require 'ess-R-object-popup) └──── • Rdired is another way to work with object • ess-rdired' • View, delete, plot, and update buffer (ala /revert/) are single key commands ┌──── │ (autoload 'ess-rdired "ess-rdired") └──── • Visualize data frames better. • ess-R-dv-ctable' • ess-R-dv-pprint' ┌──── │ (require 'ess-R-data-view) └──── • inlineR • /Not/ a competitor to org-mode' • Ultra lightweight LP, really ┌──── │ (require 'inlineR) └──── Documentation: • Whole section on native documentation; I'll re-visit as needed. • Roxygen, too. ess-developer' helps you to easily work within specific name-spaces. Rutils: key-bindings to aid real usage • C-c C-. l': List all packages in all available libraries. • C-c C-. r': List available packages from repositories listed by getOptions(‘‘repos’’)' in the current R session. • C-c C-. u': Update packages in a particular library lib and repository repos. • C-c C-. a': Search for a string using apropos. • C-c C-. m': Remove all R objects. • C-c C-. o': Manipulate R objects; wrapper for ess-rdired'. • C-c C-. w': Load a workspace file into R. • C-c C-. s': Save a work-space file. • C-c C-. d': Change the working directory for the current R session. • C-c C-. H': Use browse-url' to navigate R HTML documentation. ess-mode-silently-save' is worth a million bucks; usually I have to hand code this. As of <2014-01-31 Fri>, you need to manually load ESS when you pull it from MELPA [124]. That is totally fine with me, that is really the best way to load stuff. Out of curiosity, I read more about it here [125], but that occurred before this previous post made by the maintainers. Even the source code in ess-autoloads.el' has a license from 2012, which is before the aforementioned post. As such, this configuration step seems correct and necessary for now. Additionally, this how the user manual expects a typical manual setup to be configured. Looked a tiny bit at how R hackers are formatting their code [126] [127]. The simple (dumb) part of me suspects that C++ formatting is generally just fine [128]. There is strangely nice discussion about where temp files may be stored; specifically for cases where you edit identically-named objects and want to keep them in the same directory but per-project. That is not the need now, and it is nice to know that it is an option. Store history files and dump files in a single known location. If that location doesn't exist, then make it. ┌──── │ (setq gcr/r-dir "~/.R/") │ (defun gcr/make-warn-R-dir () │ "Handle of R directory misconfiguration." │ (interactive) │ (unless (f-directory? gcr/r-dir) │ (progn │ (message "Couldn't find %S… creating it." gcr/r-dir) │ (f-mkdir gcr/r-dir)))) │ (gcr/make-warn-R-dir) │ (setq ess-history-directory gcr/r-dir) │ (setq ess-source-directory gcr/r-dir) └──── Since I'm using ℝ for everything, configure /everything/ to be using ℝ. ┌──── │ (setq inferior-ess-program "R") │ (setq inferior-R-program-name "R") │ (setq ess-local-process-name "R") └──── Always start ess' within the curent emacs' frame, it doesn't need to be separate. ┌──── │ (setq inferior-ess-same-window nil) │ (setq inferior-ess-own-frame nil) └──── Help buffers all belong in the same frame. ┌──── │ (setq ess-help-own-frame nil) └──── When ess' starts, or when ℝ starts, it takes the current directory as its working directory. This is totally fine; so don't ask what the working directory should be. ┌──── │ (setq ess-ask-for-ess-directory nil) └──── My preference is for ESS to quit and not ask me whether or not I am sure. There is an intentional line-break after the closing round bracket because that is the approach of the original value here. ┌──── │ (setq inferior-ess-exit-command "q('no') │ ") └──── When commands are executed, display their output within the current buffer, rather than to a new dedicated buffer for them. ┌──── │ (setq ess-execute-in-process-buffer +1) └──── When you cycle between a the ℝ buffer and the script, you get to the process buffer, you will go to the end of the buffer. This setting is specifically to handle a buffer that is scrolling when you want to see the last result and will scroll back after the fact to see the history. ┌──── │ (setq ess-switch-to-end-of-proc-buffer t) └──── Use typical auto completion in buffers here, but don't do it when the next char is a symbol or closed paren. ┌──── │ (setq ess-tab-complete-in-script +1) │ (setq ess-first-tab-never-complete 'symbol-or-paren-or-punct) └──── Use ido' completion whenever possible. ┌──── │ (setq ess-use-ido t) └──── Handle rdoc and rmd files, though I have never used them… yet. ┌──── │ (add-to-list 'auto-mode-alist '("\\.rd\\'" . Rd-mode)) │ (add-to-list 'auto-mode-alist '("\\.Rmd\$" . r-mode)) └──── Use eldoc' for this mode. Always show it when the point is on a symbol. Try to keep help strings at 10 chars or less. ┌──── │ (setq ess-use-eldoc t) │ (setq ess-eldoc-show-on-symbol t) │ (setq ess-eldoc-abbreviation-style 'normal) └──── Make it really easy to search the ℝ archives for anything. ┌──── │ (local-set-key (kbd "C-c C-. S") 'ess-rutils-rsitesearch) └──── Make it really easy to do common stuff for ℝ with good keybindings. ┌──── │ (require 'ess-rutils) │ (setq ess-rutils-keys +1) └──── r-autoyas' does argument completion. I had it working nice, and didn't use it for a while, and now it doesn't work. This needs some TLC. ┌──── │ (require 'r-autoyas) │ │ (setq r-autoyas-debug t) │ (setq r-autoyas-expand-package-functions-only nil) │ (setq r-autoyas-remove-explicit-assignments nil) └──── These functions are metioned, and I am not sure where or how to use them yet, but Vitalie Spinu mentioned them as being useful: • comint-previous-matching-input-from-input' • comint-history-isearch-backward-regexp' Personal customizations for this mode. For some currently unknown reason, smartparens' only runs when you call smartparens-strict-mode' and not turn-on-smartparens-strict-mode' like it does everywhere else. For a while I used ess-eval-buffer-and-go', but now I know that it is insanely faster to use ess-eval-buffer' instead. Previously I've read people saying that, and it is true. Save two spaces showing function information in the mini-buffer. ┌──── │ (setq ess-ac-R-argument-suffix "=") └──── When I started to standardize arrows across modes, I recalled the ess' documentation and was also reminded [129] here how easy it is to customize it. Not sure where I put the notes, but long ago I researched the ℝ coding standards. [This post] by Eddelbuettel led me to believe that the ℝ [standard] definition is the best. That made me think that RRR' would be the best because it has identical settings to the C++' style at the time of the post. That makes sense to me. I only want to change one thing to make Magrittr chains easier to read. The stock RRR' indenting makes expressions trail off to the right forever. Here is how, make a copy of RRR' and change one property. ┌──── │ (setq gcr/ess-style │ (copy-alist │ (assoc 'RRR ess-style-alist))) │ (setf (nth 0 gcr/ess-style) 'GCR) │ (setf (cdr │ (assoc 'ess-continued-statement-offset │ (cdr gcr/ess-style))) │ 0) │ (add-to-list 'ess-style-alist gcr/ess-style) │ (setq ess-default-style 'GCR) └──── ┌──── │ (defun gcr/ess-mode-hook () │ (local-set-key (kbd "s-e") 'ess-switch-to-end-of-ESS) │ (local-set-key (kbd "s-x") 'r-autoyas-expand) │ (local-set-key (kbd "s-p") 'ess-R-object-popup) │ (local-set-key (kbd "s-v o") 'ess-describe-object-at-point) │ (local-set-key (kbd "s-v d") 'ess-rdired) │ (local-set-key (kbd "s-v cc") 'ess-R-dv-ctable) │ (local-set-key (kbd "s-v cp") 'ess-R-dv-pprint) │ (setq ess-S-assign-key (kbd "C-,")) │ (ess-toggle-S-assign-key t) │ (ess-toggle-underscore nil) │ (local-set-key (kbd "C-.") (lambda () (interactive) (insert " -> "))) │ (local-set-key (kbd "C-M-,") (lambda () (interactive) (insert " <<- "))) │ (local-set-key (kbd "C-M-.") (lambda () (interactive) (insert " ->> "))) │ (key-chord-define-local (kbd ",.") (lambda () (interactive) (insert " %<>% "))) │ (local-set-key (kbd "s-.") (lambda () (interactive) (insert " %>% "))) │ (local-set-key (kbd "C-0") 'ess-eval-buffer) │ (turn-on-pretty-mode) │ (r-autoyas-ess-activate) │ (visual-line-mode) │ (smartparens-strict-mode t) │ (gcr/untabify-buffer-hook) │ (fci-mode) │ (hs-minor-mode 1) │ (linum-mode) │ (gcr/turn-on-r-hide-show) │ (aggressive-indent-mode) │ (lambda () (add-hook 'ess-presend-filter-functions │ (lambda () │ (warn │ "ESS now supports a standard pre-send filter hook. Please update your configuration to use it instead of using advice."))))) │ │ (add-hook 'ess-mode-hook 'gcr/ess-mode-hook) │ │ (defun gcr/turn-on-r-hide-show () │ "Attribution: SRC https://github.com/mlf176f2/EmacsMate/blob/master/EmacsMate-ess.org" │ (when (string= "S" ess-language) │ (set (make-local-variable 'hs-special-modes-alist) '((ess-mode "{" "}" "#" nil nil))) │ (hs-minor-mode 1) │ (when (fboundp 'foldit-mode) │ (foldit-mode 1)) │ (when (fboundp 'fold-dwim-org/minor-mode) │ (fold-dwim-org/minor-mode)))) │ │ (defun gcr/Rd-mode-hook () │ (gcr/ess-mode-hook)) │ │ (add-hook 'Rd-mode-hook 'gcr/Rd-mode-hook) │ │ (defun gcr/inferior-ess-mode-hook () │ (gcr/ess-mode-hook)) │ │ (add-hook 'inferior-ess-mode-hook 'gcr/inferior-ess-mode-hook) │ │ (defun gcr/ess-rdired-mode-hook () │ "Personal customizations." │ (interactive) │ (turn-on-stripe-buffer-mode) │ (stripe-listify-buffer)) │ │ (add-hook 'ess-rdired-mode-hook 'gcr/ess-rdired-mode-hook) └──── This [130] post shares a nice setup for the assignment key; primarily if you use underscores in your variable names, which I do on occasions. After coding like this for just 10 short minutes it drove me nuts and that is totally counter intuitive to me; I never would have expected that having to type two characters to do an assignment would give me nuts. Anyway, the default behavior is just fine; hit underscore twice gives you an underscore, and one gives you an assignment! *Philosophy* The current ESS' maintainers philosophies about how to maintain an ℝ code-base make sense to me and are virtually the same as my own. Quite simply, the rule is that the code artifacts are the single source of system definition. Consequently, the system should be configured in this manner: We want to keep dump files after loading them; never delete them. The idea is that if we use them, then they are a valid part of the system definition and need to be kept. ┌──── │ (setq ess-keep-dump-files +1) └──── ESS' allows us to quite easily modify live 𝕊 objects and functions. It provides this functionality via ess-dump-object-into-edit-buffer'. These changes are considered to be experimental, and not part of the master record according to our philosophy. As such, we don't care to know that these new versions ever existed and their record will be forgotten from history. In other words, that new, modified version of the object or function, is never saved to a file for later reuse. ┌──── │ (setq ess-delete-dump-files nil) └──── Since our systems are entirely file-based, the entirety of the system most likely lives in different files. Before loading any file for sourcing, save any ESS source buffers. This approach is in addition to two other things: (1) Emacs is auto-saving every file buffer quite frequently and (2) there is advice before every manual eval' call so that the buffers and their files stay in sync. Yes, it is really that important. ┌──── │ (setq ess-mode-silently-save +1) └──── During the experimental mode of system development, you are likely to hack on things using an ESS buffer associated with a file. Things can happen quite unexpectedly, and it is easier to know that the code that you have eval''d is the value that is actually currently saved on-disk. You get it by now, that is my personal preference. It is just a lot easier IMHO to know that your files are persisted and my be stored in your VCS and that things "look are right". ┌──── │ (defadvice ess-eval-region-or-line-and-step (before before-ess-eval-region-or-line-and-step activate) │ (gcr/save-all-file-buffers)) │ │ (defadvice ess-eval-region-or-function-or-paragraph (before before-ess-eval-region-or-function-or-paragraph activate) │ (gcr/save-all-file-buffers)) │ │ (defadvice ess-eval-region-or-function-or-paragraph-and-step (before before-ess-eval-region-or-function-or-paragraph-and-step activate) │ (gcr/save-all-file-buffers)) │ │ (defadvice ess-eval-line (before before-ess-eval-line activate) │ (gcr/save-all-file-buffers)) │ │ (defadvice ess-eval-line-and-go (before before-ess-eval-line-and-go activate) │ (gcr/save-all-file-buffers)) │ │ (defadvice ess-eval-function (before before-ess-eval-function activate) │ (gcr/save-all-file-buffers)) │ │ (defadvice ess-eval-function-and-go (before before-ess-eval-function-and-go activate) │ (gcr/save-all-file-buffers)) │ │ (defadvice ess-eval-region (before before-ess-eval-region activate) │ (gcr/save-all-file-buffers)) │ │ (defadvice ess-eval-region-and-go (before before-ess-eval-region-and-go activate) │ (gcr/save-all-file-buffers)) │ │ (defadvice ess-eval-buffer (before before-ess-eval-buffer activate) │ (gcr/save-all-file-buffers)) │ │ (defadvice ess-eval-buffer-and-go (before before-ess-eval-buffer-and-go activate) │ (gcr/save-all-file-buffers)) └──── Don't save the workspace when you quit ℝ and don't restore *ANYTHING* when you start it, either. This adheres to the philosopy that the system is file based. Period. ┌──── │ (setq inferior-R-args "--no-save --no-restore") └──── Indent curly brackets correctly: smartparens' is serving me well. In this mode it is for curly, round, and square brackets. ESS' handles indenting mostly right, too. One thing was unpleasant, though. When you define a new function, hitting return brings the curely bracket down to the newline but doesn't give it an empty line and indent the cursor one indentation over so that you may begin implementing the function. That is a big hassle; 4 unnecessary keystroke, it is really distracting and takes you out of the flow. It is such a little thing yet it is so powerfully distracting. It is like a mosquito in your tent! Searching for a solution revealed that I am not alone here. This post [131] handles brackets, indentation quite well [132] but doesn't provide the behavior that I want. This post [133] captured exactly what I was facing, yet didn't end with a solution which was kind of shocking. Searching some more I ended up here [134], and this seems like the ideal solution by the author of smartparens himself. This is probably a common thing as I found another post with exactly my situation referencing that aforementioned solution, too [135]. This is a nice generalizable approach that should serve me well for just about everything in this solution-area. Here [136] is a post showing a more advanced usage that handles context which is nice to know is an option. ┌──── │ (sp-local-pair 'ess-mode "{" nil :post-handlers '((gcr/indent-curly-block "RET"))) └──── ESS' executes code in another process. That is no secret. When displaying output from that code running in another process though, it can look like Emacs is locking up. That is not the case [137]. What is happening that Emacs is waiting for the output. Configure this mode to continue to accept user input, which is obviously critical, but don't wait for the process to provide its output. Instead, all output is printed after the last input lines. What we gain is perceived speed, and what we lose is the nice sequential this/that/this/that we get from a typical REPL interaction. As I write this, I'm not totally sure how this will work, but the documentation and post are consistent and describe what I had wanted here so I will give it a try and see how it goes. ┌──── │ (setq ess-eval-visibly 'nowait) └──── Michael explained how to use a richer eval-expression', and then showed how to do the same thing in ℝ. This is the original post, and it will work once I am on the next version of emacs' that has the new advice library. Until then, I won't include this. ┌──── │ (advice-add │ 'debugger-record-expression :around │ (lambda (f exp) (interactive │ (list (read (my-read--expression "Record Eval: ")))) │ (funcall f exp)) │ '((name . use-my-read--expression))) └──── [This post] http://stackoverflow.com/questions/7502540/make-emacs-ess-follow-r-style-guide [standard] http://cran.r-project.org/doc/manuals/R-ints.html#R-coding-standards 6.31 Org ──────── This section takes about 15 seconds to tangle. 6.31.1 Discussion ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ Late into the development process I ran into some export to HTML issues. After tracking down the source, I learned that tracking down the source of the issue in the source itself was out of scope for me. My solution was to break out the org-mode configuration into its own block so that I could generate two Emacs configuration files. Doing so with a different section was easier, so that is how I did it. Tangling can take more than a few minutes; so there is some advice to report on it just to me understand what is happening and that it is working. Another way to perform this monitoring would have been to use around advice. What I ran into is that on HTML export around works fine, but on tangling it did not. This is something that I chose not to investigate; instead I reverted the tangling advice to two separate commands and that seems to work fine. Org mode, like most of Emacs more powerful modes, slowly grows on you, in pleasant and intuitive ways. Pretty soon, you fall in love with it. After using it for 50+ hours or so you start wanting some easier way to navigate then by typing in the commands over and over (doesn't matter how you re-run them). Reading the miscellaneous section, I learned about speed keys [138] [139]. Wonderful, just wonderful. Visualizing hierarchical lists in a flat manner has been fine for me. Sometimes though I wanted to depth-based view, but didn't think much more of it. Reading abouto org-mode, I came upon org-indent-mode' [140], and decided to give it a try for a while because it is kind of easier to read. Both modes are nice, and thus far I'm switching back and force as I feel like it. Once I opened my eyes and learned about org-hide-leading-stars' though, I really found happiness. One topic relating to color themes is that of how code should look within a source block in an org file. There was a thread asking about how to make the block coloring "better". It was interesting because it revealed my preference to myself namely that source blocks should be a muted Gray in the document because it shouldn't draw much attention, but in the editor of course you get the highlighting that you want. That is really my personal preference, nonetheless, org-src-fontify-natively' is still always an option. Over the past six months I think, this approach has worked out well. Nonetheless I got curious about how things /might/ be with coloring turned on. Generally, it looks fine. Strangely though, even with the solarized' these it is kind of distracting. Beyond sharing that observation, I won't quantify it any more than that. The biggest thing for me is that I only want to edit source blocks in their "real" mode because: • The real mode is present and as such • All mode specific bindings are present • Worth mentioning twice because if I don't have helpers on then I will not match brackets manually! • I've broken code so many times making "quick fixes" and breaking the bracket matching it is exhausting • Sending code to REPLs • May not sound like much, but those three things are very, very huge in my work-flow The good news is that for doing code reviews and stuff, I can always turn on that fontification. On a somewhat similar thread, (setq org-src-tab-acts-natively t)' would make it easier to edit source blocks outside of the vehicle offered by org-edit-src-code'. Since my intent is never to edit blocks outside for their proper mode though, I will not enable that. This approach of mine, I think I touch upon it elsewhere… at some point I would like to refactor this whole document. This [141] article is really fascinating in that crams a ton of information into a tiny space. It also is kind of fun to read because it simultaneously teaches you so many new things, yet at the same time re-teaches or re-educates you about things that you already knew but didn't know that you could or should be using in these additional manners. The HTML export of org documents has an optional JavaScript supported display [142]. Not sure how I ended up on this, but it is actually a very nice option. The info style view is nice once you read the directions. The folding interface is also interesting; I tried out all 3 generation options but didn't find anything that I specifically liked. Perhaps it is a familiarity or comfort level with GNU styled docs or the key-bindings. Don't use org' for time-tracking, but if I ever do then [143] this is nice to know of. 6.31.2 Configuration ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ For this feature to work, it must come /before/ any org' load statements ┌──── │ (setq org-list-allow-alphabetical +1) └──── ◊ 6.31.2.1 Org org' intelligently chose not to autoload' everything. The most noticeable things in the require statements for org' are that: • Only a few exporters come built in hence the need to require them • htmlize' is required for pretty HTML export of code <2014-11-18 Tue> There is a development occurring here, figuring out how to migrate off of Cask for package management. Thus far, el-get seems to handle everything, but for org. Because org is the only package that I will ever install via package, it goes here for now. I didn't stick with that, and moved it to package 100% <2014-11-20 Thu>. ┌──── │ (require 'org) │ (require 'ox-beamer) │ (require 'ox-md) │ (require 'htmlize) └──── Exports to Confluence are very very helpful. ┌──── │ (require 'ox-confluence) └──── htmlize' should eventually be moved out of this org' block into its own re-usab.e section. It does need configuring both for org' and also for general use. I like to be able to copy-and-paste its generated HTML into other documents, and css' is the easiest way to achieve it. At some future date, it would be nice to developer a proper style sheet to handle any situation. The problem is that right now I don't have enough situations to based a design upon, just the desire to do so. My preference for styling HTML documents has been the same as all printable documents: black and white. When you do a htmlize' export in batch-mode, there is no bufer style information to be exported, so you get nice black-and-white code formatting. This is an acceptable approach, but I am getting close to setting up a style to product just what I want for HTML export. It is close enough to almost require investment to address it. ┌──── │ (setq htmlize-output-type 'inline-css) │ (setq org-html-htmlize-output-type htmlize-output-type) └──── org-show' need special handling, see the install for details. ┌──── │ (let ((pkg 'org-show)) │ (gcr/on-gui │ (if (not (el-get-package-is-installed pkg)) │ (warn "You wanted %S to be installed, but it isnt. Fix this." pkg) │ (let ((fil (concat (el-get-package-directory pkg) "org-show.el"))) │ (if (not (f-exists? fil)) │ (warn "You wanted %S to exist, but it doesn't. Fix this." fil) │ (load fil))))) │ (gcr/not-on-gui (warn "You wanted %S to be loaded, but it won't be… it doesn't work without a GUI for some reason." pkg))) └──── Building org' documents is intimately tied to: • The org' version • The init' version used to configure org • Check the former • Perhaps someday the latter should be checked? ┌──── │ (defconst gcr/org-version "8.2.10") │ │ (defun gcr/warn-org-version () │ "Warn of org misconfiguration." │ (interactive) │ (when (not (version= (org-version) gcr/org-version)) │ (warn "Insufficient org-mode requirements. Expected %S. Found: %S " gcr/org-version (org-version)))) │ (gcr/warn-org-version) └──── Make sure that exported files are Unicode UFT-8. ┌──── │ (setq org-export-coding-system 'utf-8) └──── Do not preserve line-breaks when exporting instead let the destination format handle it as it sees fit. ┌──── │ (setq org-export-preserve-breaks nil) └──── My personal TODO workflow is pretty tame, and it is defined below. ┌──── │ (setq org-todo-keywords │ '((sequence "TODO" "IN-PROGRESS" "WAITING" "REVIEW" "DONE"))) └──── When running in a GUI, I would like linked images to be displayed inside of Emacs. ┌──── │ (setq org-startup-with-inline-images (display-graphic-p)) └──── When exporting anything, do not insert the exported content intto the kill ring. ┌──── │ (setq org-export-copy-to-kill-ring nil) └──── Use ido' completion in org'. ┌──── │ (setq org-completion-use-ido +1) └──── org' lets you use single letter commands to do stuff on headers. I like to use c' for cycling the header expansion. ┌──── │ (setq org-use-speed-commands +1) └──── Ask before execution of shell links. This may look inconsistent given that I allow evaluation. It just looks inconsistent. ┌──── │ (setq org-confirm-shell-link-function 'y-or-n-p) └──── Ask before execution of emacs-lisp links. This may look inconsistent given that I allow evaluation. It just looks inconsistent. ┌──── │ (setq org-confirm-elisp-link-function 'y-or-n-p) └──── Make sure that incomplete TODO entries prevent the enclosing parent from every turning to DONE. ┌──── │ (setq org-enforce-todo-dependencies +1) └──── Allow the mouse to do org' things like expand and collapse headings. ┌──── │ (gcr/on-gui │ (require 'org-mouse)) └──── Use unicode characters to visualize things like right arrow eg →. ┌──── │ (setq org-pretty-entities +1) └──── Use a real ellipsis to render an ellipsis for org' stuff like showing that a header is collapsed. ┌──── │ (setq org-ellipsis "…") └──── It is easy to see indentation of headlines without having to count asertisks, so don't show them, only show the significant and last one. ┌──── │ (setq org-hide-leading-stars +1) └──── Display emphasized text as you would in a WYSIWYG editor. ┌──── │ (setq org-fontify-emphasized-text +1) └──── Highlight LaTeX markup. Normally, I don't do any syntax highlighting, as I believe that should be delegated to source buffers, thinking that to do otherwise is distracting. However, I already do configure subscripts and Greek letters to be displayed with syntax highlighting, because I want to indicate to the human reader that they are special, and specifically /not/-Unicode. Do the same thing for ┌──── │ (setq org-highlight-latex-and-related '(latex script entities)) └──── There is an auto-complete provider for org-mode [144]. Nice as I didn't even think to check. Perhaps a check should go on the standard setup list. This seems to work when you type out things like block definitions; and it won't apply to EasyTemplate generated regions. auto-complete' will still work on them, though: ┌──── │ (require 'org-ac) │ (org-ac/config-default) └──── Footnote management is an important topic. Thanks to Richard [145], there is a concise approach for this, which I've pasted here: ┌──── │ I use the inline footnote syntax [fn:: ...] for just this reason. I │ think easy migration of non-inline footnotes would be a nice feature to │ add to Org, though doing it right would be non-trivial. │ │ A strategy that another user once described to me for dealing with this │ problem is the following: │ │ 1) Use a regexp search and replace to re-number the footnotes │ in the region of the text you want to move, giving them high numbers │ (e.g., prefixing each with "9999"). │ 2) Use Org to re-sort the footnotes in the original file, so that the │ newly-renumbered footnotes all appear at the end. │ 3) Move the text and the footnotes to the new file, which should now be │ easy, since the footnotes are all grouped together. │ 4) In the new file, use Org to re-number the footnotes back to something │ normal. │ │ This sounded like a pretty good idea to me, though I haven't had a need │ to try it myself. │ │ Hope that helps! │ │ Best, │ Richard └──── ┌──── │ (setq org-footnote-define-inline +1) │ (setq org-footnote-auto-label 'random) │ (setq org-footnote-auto-adjust nil) │ (setq org-footnote-section nil) └──── This is an amazingly easy way to screw up your document. The more you edit org docs, the more you realize how you must truly protect it: ┌──── │ (setq org-catch-invisible-edits 'error) └──── Though I am not deliving deep, it is hard not to want to customize some stuff and perhaps this is the start: ┌──── │ (setq org-loop-over-headlines-in-active-region t) └──── By default I never want a table of contents generated. It is so easy to enable it with a property, it will be fine to turn it off. ┌──── │ (setq org-export-with-toc nil) └──── It is /almost always/ faster to work with org documents when they are fully expanded. Anyway, the structure cycling makes it really, really easy to get an /outline view/ again. ┌──── │ (setq org-startup-folded "nofold") └──── When images are displayed in the buffer, display them in their actual size. My goal is to use other tools to make the image compliant what I want rather than have to mess and fiddle with image resizing in org'. ┌──── │ (setq org-image-actual-width t) └──── Hide the delimeter for emphasized text. This may break table alignment. ┌──── │ (setq org-hide-emphasis-markers +1) └──── Realign tables automatically. ┌──── │ (setq org-startup-align-all-tables +1) └──── ◊ 6.31.2.2 Babel There is a hook for things to do after a source block has been executed. These are my preferences for what should happen. This tip appeared in this [146] discussion and Nick Dokos agreed here that [147] that it is the ideal approach because it does /not/ interfere with export. This thread [148] explained the correct approach as of <2015-01-22 Thu>, which meant a simpler function call. ┌──── │ (defun gcr/org-babel-after-execute-hook () │ "Personal settings for the org-babel-after-execute-hook'." │ (interactive) │ (org-redisplay-inline-images)) │ │ (add-hook 'org-babel-after-execute-hook 'gcr/org-babel-after-execute-hook) └──── Load the ob-sml' package. Perhaps some day it will end up in the mainline. ┌──── │ (require 'ob-sml nil 'noerror) └──── Tell org' that it may evaluate all of the listed languages. ┌──── │ (org-babel-do-load-languages │ 'org-babel-load-languages │ '((calc . t) │ (css . t) │ (dot . t) │ (ditaa . t) │ (emacs-lisp . t) │ (js . t) │ (latex . t) │ (lilypond . t) │ (makefile . t) │ (org . t) │ (perl . t) │ (python . t) │ (plantuml . t) │ (R . t) │ (scheme . t) │ (sh . t) │ (sml . t) │ (sql . t))) └──── There is a way to disable property inheritance that speeds up tangling a lot. The problem is that you lose property inheritance which is unacceptable. Never, never allow that. ┌──── │ (setq org-babel-use-quick-and-dirty-noweb-expansion nil) └──── You may display syntax highlighting for code in source blocks. I don't. ┌──── │ (setq org-src-fontify-natively nil) └──── On export, maintain the literal spacing as found in the source block. Obviously this is important for makefiles. It is really important everywhere because anything else would violate the law of least surprise. ┌──── │ (setq org-src-preserve-indentation +1) └──── When source blocks are exported, do not indent them arbitrarily. This does nothing given that the previous setting is non-null; however I believe that I set this for a reason that I may no longer recall. ┌──── │ (setq org-edit-src-content-indentation 0) └──── When edit mode is exited, the option exists to automatically remove empty opening and closed lines for the source block. Never do this. ┌──── │ (setq org-src-strip-leading-and-trailing-blank-lines nil) └──── For code blocks that I use a *lot*, add templates for source blocks because my current approach is to do a \n?\n")) └──── OOTB the templates are all upper case. Case shouldn't matter inside of org', but on my system it breaks org'. This needs to be investigated, and until then I will just downcase all of the templates. ┌──── │ (mapc (lambda (asc) │ (let ((org-sce-dc (downcase (nth 1 asc)))) │ (setf (nth 1 asc) org-sce-dc))) │ org-structure-template-alist) └──── It looks like ℝ is going to be another one, but don't process it to downcase it… order matters here. ┌──── │ (add-to-list │ 'org-structure-template-alist │ '("r" "#+begin_src R\n?\n#+end_src" "")) │ (add-to-list │ 'org-structure-template-alist │ '("p" "#+begin_src plantuml\n?\n#+end_src" "")) │ (add-to-list │ 'org-structure-template-alist │ '("sh" "#+begin_src sh\n?\n#+end_src" "")) └──── Sometimes tangling and exporting takes a long time and I would like to see some status messages. Shell commands can report duration, too. ┌──── │ (defadvice org-babel-tangle (before org-babel-tangle-before activate) │ (gcr/save-all-file-buffers) │ (message (concat "org-babel-tangle BEFORE: <" │ (format-time-string "%Y-%m-%dT%T%z") │ ">")) │ (setq gcr/tmp (current-time))) │ │ (defadvice org-babel-tangle (after org-babel-tangle-after activate) │ (let* ((dur (float-time (time-since gcr/tmp))) │ (msg (format "Tangling complete after: %.06f seconds" dur))) │ (message (concat "org-babel-tangle AFTER: <" │ (format-time-string "%Y-%m-%dT%T%z") │ ">")) │ (message msg) │ (gcr/on-gui (alert msg :title "org-mode")))) │ │ (defadvice org-ascii-export-as-ascii (before org-ascii-export-as-ascii-before activate) │ (gcr/save-all-file-buffers)) │ │ (defadvice org-html-export-to-html (before before-org-html-export-to-html activate) │ (gcr/save-all-file-buffers) │ (message (concat "org-html-export-to-html BEFORE: <" │ (format-time-string "%Y-%m-%dT%T%z") │ ">"))) │ │ (defadvice org-html-export-to-html (after after-org-html-export-to-html activate) │ (message (concat "org-html-export-to-html AFTER: <"