# -- Default template #+TITLE: ALEC's a Language for Expressing Creativity (ALEC) #+DATE: <2014-02-24 MON> #+AUTHOR: Grant Rettke #+EMAIL: gcr@wisdomandwonder.com #+OPTIONS: ':nil *:t -:t ::t <:t H:3 \n:nil ^:t arch:headline author:t c:nil #+OPTIONS: creator:comment d:(not "LOGBOOK") date:t e:t email:nil f:t inline:t #+OPTIONS: num:t p:nil pri:nil stat:t tags:t tasks:t tex:t timestamp:t toc:5 #+OPTIONS: todo:t |:t #+STARTUP: showeverything #+CREATOR: Emacs 24.4.1 (Org mode 8.2.10) #+DESCRIPTION: This document realizes ALEC using Emacs. #+EXCLUDE_TAGS: noexport #+KEYWORDS: literate programming, reproducible research, programming language, lisp, elisp, ide, emacs, babel, org-mode #+LANGUAGE: en #+SELECT_TAGS: export # -- ASCII template # -- HTML template #+OPTIONS: html-link-use-abs-url:nil html-postamble:auto html-preamble:t #+OPTIONS: html-scripts:t html-style:t html5-fancy:nil tex:t #+CREATOR: Emacs 24.3.1 (Org mode 8.2.7) #+HTML_CONTAINER: div #+HTML_DOCTYPE: xhtml-strict #+HTML_HEAD: #+HTML_HEAD_EXTRA: #+HTML_LINK_HOME: #+HTML_LINK_UP: #+HTML_MATHJAX: #+INFOJS_OPT: view:info toc:5 #+LATEX_HEADER: # -- Latex template #+DATE: <2014-02-24 MON> #+OPTIONS: texht:t #+LATEX_CLASS: article #+LATEX_CLASS_OPTIONS: [letterpaper, 10pt] #+LATEX_HEADER: \usepackage[paperwidth=8.5in, paperheight=11in, hmargin=0.5in, vmargin=0.5in]{geometry} #+LATEX_HEADER_EXTRA: #+STARTUP: showeverything * Start Up :PROPERTIES: :noweb-ref: Start-Up :END: 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. #+begin_src emacs-lisp (setq load-prefer-newer t) #+end_src * Run-time :PROPERTIES: :noweb-ref: Runtime-Check :END: 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 #+begin_src emacs-lisp (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) #+end_src * Provisioning :PROPERTIES: :noweb-ref: Provisioning :END: ** 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. ** Steps *** 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. #+begin_src emacs-lisp (package-initialize) #+end_src 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. #+begin_src emacs-lisp (add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/") t) #+end_src GNU stuff is always good. #+begin_src emacs-lisp (add-to-list 'package-archives '("gnu" . "http://elpa.gnu.org/packages/")) #+end_src MELPA is critical. #+begin_src emacs-lisp (add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/") t) #+end_src If Package+ is not installed, then install it. First the package list has to be refreshed so that Package knows about the new packages. #+begin_src emacs-lisp (package-refresh-contents) (unless (package-installed-p 'package+) (package-install 'package+)) #+end_src This is the list of packages that should be installed automatically and loaded. Any packages not listed here that Package+ finds are removed. #+begin_src emacs-lisp (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 ) #+end_src 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. #+begin_src emacs-lisp (load-library "f") #+end_src *** el-get EL-Get handles things that don't easily fit anywhere else. Initialize EL-Get. #+begin_src emacs-lisp (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))) #+end_src #+begin_src emacs-lisp (setq gcr/el-get-packages nil) #+end_src =org-show= [fn:5de243c0: https://github.com/jkitchin/jmax/blob/master/org-show.org] 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 #+begin_src emacs-lisp (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) #+end_src Make it really easy to remind yourself and others what EMACS really stands for (in this case it is fun). #+begin_src emacs-lisp (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) #+end_src 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. #+begin_src emacs-lisp (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) #+end_src People love horoscopes, so, provide them. #+begin_src emacs-lisp (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) #+end_src James Parry [fn:c99fd633: https://en.wikipedia.org/wiki/James_Parry] must always be honored. #+begin_src emacs-lisp (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) #+end_src You might not always remember your shopping list, but we will remember it for you… though not necessarily for wholesale. #+begin_src emacs-lisp (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) #+end_src Do you remember when those great AT&T adds were on television and it changed your life and bought you a kitten? You will. #+begin_src emacs-lisp (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) #+end_src A swimming-pool screen-saver. #+begin_src emacs-lisp (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) #+end_src #+begin_src emacs-lisp (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) #+end_src Today the recipe didn't work, =el-get= couldn't find it. That is pretty bizarre because /nothing changed/. The recipe still lives here [fn:b7460ca0: https://github.com/dimitri/el-get/blob/master/recipes/sicp.rcp]. 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. #+begin_quote =(add-to-list 'gcr/el-get-packages 'sicp)= #+end_quote As el-get to make sure that those desired packages are installed. #+begin_src emacs-lisp (el-get 'sync gcr/el-get-packages) #+end_src * 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. * 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. ** 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 [fn:2e3b75ad: https://www.cs.indiana.edu/~rpjames/]: #+BEGIN_QUOTE 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. #+END_QUOTE Even more succinctly, my measure of success is to: #+BEGIN_CENTER To provide a self-suportable environment in which the creation and conservation of computer files may occur with ease #+END_CENTER 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 [fn:54b16b1c: https://www.gnu.org/software/emacs/]. With that in mind, the following is what I actually want to do with it. ** 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 ** Inspirations - Eric Weisstein :: Creator of MathWorld [fn:f0123b05: http://mathworld.wolfram.com/about/author.html] * Means :PROPERTIES: :noweb-ref: Means :END: 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. ** Functions & Constants #+begin_src emacs-lisp (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)))) #+end_src 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= #+begin_src emacs-lisp (defun gcr/newline () "Locally binds newline." (local-set-key (kbd "RET") 'sp-newline)) #+end_src #+begin_src emacs-lisp (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)) #+end_src 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=. #+begin_src emacs-lisp (defun gcr/util-cycle () "Display or hide the utility buffers." (interactive) (if gcr/util-state (gcr/util-stop) (gcr/util-start))) #+end_src Unfill paragraph: because I should have quit doing this by hand 400 posts ago. #+begin_src emacs-lisp (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))) #+end_src ** 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. #+begin_src emacs-lisp (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) #+end_src ** Windows Menu bars are not required. Curiously, I've come to like the menu bar specifically when working with other people! #+begin_src emacs-lisp (menu-bar-mode +1) #+end_src For some reason, on OSX dialogues don't work and essentially end up locking up Emacs! Here [fn:af30569b: https://superuser.com/questions/125569/how-to-fix-emacs-popup-dialogs-on-mac-os-x] is the solution: #+begin_src emacs-lisp (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))) #+end_src ** 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. #+begin_src emacs-lisp (require 'exec-path-from-shell) (gcr/on-osx (exec-path-from-shell-initialize)) #+end_src #+RESULTS: 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 [fn:4f2e6828: http://melpa.milkbox.net/#/todochiku] due to the high download count but two issues, it didn't work and it is not used by anything else. Alert [fn:fd4688ce: http://melpa.milkbox.net/#/alert], on the other hand, is, and also lives on Github meaning that it is maintainable. #+begin_src emacs-lisp (require 'alert) (setq alert-fade-time 10) (gcr/on-gui (gcr/on-osx (setq alert-default-style 'growl))) (setq alert-reveal-idle-time 120) #+end_src On Windows, you need to specify a specific shell so that Emacs can talk to other programs in the correct manner: #+begin_src emacs-lisp (gcr/on-windows (setq shell-file-name "cmdproxy.exe")) #+end_src Enable the =super= key-space: #+begin_src emacs-lisp (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)) #+end_src ** 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 [fn:c3cd65d8: http://emacs.wordpress.com/2007/01/16/quick-and-dirty-code-folding/] 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: [fn:425c5a43: http://www.emacswiki.org/emacs/OutlineMode][fn:80e6214c: http://www.emacswiki.org/emacs/FoldingMode][fn:160: https://github.com/zenozeng/yafolding.el][fn:82e77bec: http://cedet.sourceforge.net/]. If you know org-mode, then using that style of control makes it easier to use then the built in bindings for hideshow [fn:30f9d745: https://www.gnu.org/software/emacs/manual/html_node/emacs/Hideshow.html], 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. #+begin_src emacs-lisp (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))) #+end_src ** Buffers Show line numbers everywhere. [fn:bab178f9: http://git.savannah.gnu.org/cgit/emacs.git/tree/lisp/linum.el?h=emacs-24] 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. #+begin_src emacs-lisp (global-linum-mode -1) #+end_src Activate syntax highlighting everywhere. [fn:0dc4ff83: https://www.gnu.org/software/emacs/manual/html_node/emacs/Font-Lock.html] #+begin_src emacs-lisp (global-font-lock-mode 1) #+end_src 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: #+begin_src emacs-lisp (setq aw-keys '(?a ?s ?d ?f ?j ?k ?l ?\;)) #+end_src Visualize parentheses a certain way. [fn:b352291c: https://www.gnu.org/software/emacs/manual/html_node/emacs/Matching.html] #+begin_src emacs-lisp (setq blink-matching-paren nil) (show-paren-mode +1) (setq show-paren-delay 0) (setq show-paren-style 'expression) #+end_src Don't use audible bells, use visual bells. [fn:00bb2e9a: https://www.gnu.org/software/emacs/manual/html_node/elisp/Beeping.html] #+begin_src emacs-lisp (setq ring-bell-function 'ignore) (setq visible-bell +1) #+end_src This post [fn:ea94a54c: http://www.wisdomandwonder.com/link/8533/avoiding-window-takeover-in-emacs] 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 [fn:13e4e7a4: https://www.gnu.org/software/emacs/manual/html_node/emacs/Window-Convenience.html] [fn:f0518791: http://irreal.org/blog/?p=1557], 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. #+begin_src emacs-lisp (winner-mode +1) #+end_src When the time is right, I'll look into Workgroups for Windows [fn:874dad92: https://github.com/tlh/workgroups.el] or its friends. The cursor should not blink. [fn:5873530d: https://www.gnu.org/software/emacs/manual/html_node/emacs/Cursor-Display.html] #+begin_src emacs-lisp (blink-cursor-mode 0) (gcr/on-gui (setq-default cursor-type 'box)) (setq x-stretch-cursor 1) #+end_src Make deleting an entire line work how you may expect [fn:f3160ceb: http://www.wilfred.me.uk/.emacs.d/init.html#sec-3-7] #+begin_src emacs-lisp (defadvice kill-line (around kill-line-remove-newline activate) (let ((kill-whole-line t)) ad-do-it)) #+end_src 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 [fn:cbacf0d5: https://github.com/alpaker/Fill-Column-Indicator]. 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. [fn:acc1a645: http://stable.melpa.org/#/fill-column-indicator] #+begin_src emacs-lisp (setq-default fill-column 80) #+end_src Something that I never missed from Idea was version control status info in the fringe, just never used it. Then when I saw it [fn:27efe175: https://github.com/dgutov/diff-hl] 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. #+begin_src emacs-lisp (global-diff-hl-mode) #+end_src 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: [fn:29f58393: https://github.com/magnars/expand-region.el] #+begin_src emacs-lisp (require 'expand-region) #+end_src 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 [fn:bb3b4f83: https://github.com/winterTTr/ace-jump-mode] 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 [fn:e4201d0c: https://github.com/winterTTr/ace-jump-mode/wiki/AceJump-FAQ]. The idea is so deceptively simple, and when you grok it, you will be truly shocked. The author sums it up quite succinctly #+begin_src emacs-lisp (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) #+end_src Keep open files open across sessions. [fn:1d393334: https://www.gnu.org/software/emacs/manual/html_node/emacs/Saving-Emacs-Sessions.html#Saving-Emacs-Sessions] 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. #+begin_src emacs-lisp (desktop-save-mode 1) (setq desktop-restore-eager 10) #+end_src Automatically save every buffer associated with a file [fn:893e2436: http://marmalade-repo.org/packages/real-auto-save]. 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 [fn:7d587f95: http://lexfridman.com/blogs/research/2011/06/26/auto-save-files-in-emacs/] which gives me what I want, since I seemingly couldn't figure that out myself in the past! #+begin_src emacs-lisp (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) #+end_src Bozhidar shared how to get even more default save behavior similar to Idea [fn:e6e85738: http://batsov.com/articles/2012/03/08/emacs-tip-number-5-save-buffers-automatically-on-buffer-or-window-switch/]. #+begin_src emacs-lisp (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))) #+end_src Make two buffers with the same file name open distinguishable. [fn:de75200e: https://www.gnu.org/software/emacs/manual/html_node/emacs/Uniquify.html] #+begin_src emacs-lisp (require 'uniquify) (setq uniquify-buffer-name-style 'forward) #+end_src Support transparent AES encryption of buffers. [fn:5743c74c: http://ccrypt.sourceforge.net/#emacs] See also for library paths [fn:58592a74: https://www.gnu.org/software/emacs/manual/html_node/emacs/Lisp-Libraries.html] #+begin_src emacs-lisp (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") #+end_src With modern VCS, backup files aren't required. [fn:4c56e8e0: https://www.gnu.org/software/emacs/manual/html_node/elisp/Making-Backups.html] #+begin_src emacs-lisp (setq backup-inhibited 1) #+end_src Ban white-space at end of lines, globally. [fn:cb5158b0: https://www.gnu.org/software/emacs/manual/html_node/emacs/Useless-Whitespace.html] #+begin_src emacs-lisp (add-hook 'write-file-hooks (lambda () (gcr/delete-trailing-whitespace))) #+end_src The world is so rich with expressivity. Although Unicode may never capture all of the worlds symbols, it comes close. [fn:01abb328: https://www.gnu.org/software/emacs/manual/html_node/emacs/International.html#International] [fn:0f1757b6: https://www.gnu.org/software/emacs/manual/html_node/emacs/Recognize-Coding.html] [fn:0242be7c: https://www.gnu.org/software/emacs/manual/html_node/emacs/Output-Coding.html] #+begin_src emacs-lisp (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))) #+end_src 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 [fn:96d1a4e4: http://permalink.gmane.org/gmane.emacs.ess.general/8332]. Emacs has a powerful buffer tracking change system. Unfortunately, I don't understand any of it. Undo should "just work". #+begin_src emacs-lisp (require 'undo-tree) (global-undo-tree-mode 1) (gcr/diminish 'undo-tree-mode) #+end_src 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. #+begin_src emacs-lisp (setq require-final-newline t) #+end_src Speaking of line endings just read this [fn:21bec4d5: https://www.reddit.com/r/emacs/comments/2g6huy/how_to_default_to_crlf_endings_for_windowscentric/]. 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. #+begin_src emacs-lisp (global-auto-revert-mode 1) #+end_src This [fn:d95e8aea: http://endlessparentheses.com/permanent-auto-indentation.html] 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= [fn:fd94462d: https://github.com/rejeep/wrap-region.el] 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. #+begin_src emacs-lisp (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 #+end_src Usually you actually need two scratch buffers, one for Emacs lisp and one for text: #+begin_src emacs-lisp (let ((text-buffer (get-buffer-create "*text*"))) (with-current-buffer text-buffer (text-mode) (insert "Shall we play a game?") (beginning-of-line))) #+end_src 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 [fn:4ab3a68a: https://github.com/davep/boxquote.el] seems like a nice way to make it obvious when I insert quoted text: #+begin_src emacs-lisp (require 'boxquote) #+end_src 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: #+begin_src emacs-lisp (setq track-eol +1) (setq line-move-visual nil) #+end_src 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. #+begin_src emacs-lisp (global-set-key [?\C-x ?t] 'anchored-transpose) (autoload 'anchored-transpose "anchored-transpose" nil t) #+end_src For a long while I used =tabbar= [fn:11b925fe: http://www.emacswiki.org/emacs/TabBarMode] 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= [fn:167d949c: http://www.emacswiki.org/emacs/IbufferMode] [fn:29b94e55: http://emacs-fu.blogspot.fr/2010/02/dealing-with-many-buffers-ibuffer.html] to let me do it. Joking aside, purcell's approach [fn:e46c420a: https://github.com/purcell/ibuffer-vc] 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 [fn:d801c7b7: https://github.com/grettke/stathon], 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! #+begin_src emacs-lisp (require 'ibuffer) #+end_src 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. #+begin_src emacs-lisp (require 'smooth-scrolling) #+end_src Sometimes it is difficult to comprehend tabular data inside of a buffer, so make it easier. #+begin_src emacs-lisp (require 'stripe-buffer) #+end_src 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. #+begin_src emacs-lisp (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)) #+end_src #+begin_quote In my world, sentences end with a single space. This makes sentence navigation commands work for me. [fn:85c41faf: https://github.com/sachac/.emacs.d/blob/gh-pages/Sacha.org] #+end_quote #+begin_src emacs-lisp (setq sentence-end-double-space nil) #+end_src Visual-line-mode is really, really great. When it is running, I don't need to know about it. #+begin_src emacs-lisp (gcr/diminish 'visual-line-mode) #+end_src Hide-show is another sweet mode that I don't need to know is running. #+begin_src emacs-lisp (eval-after-load "hideshow" '(diminish 'hs-minor-mode)) #+end_src ** Frames Make the title frame something special. #+begin_src emacs-lisp (gcr/on-osx (setq frame-title-format '("𝔸𝕃𝔼ℂ"))) (gcr/on-windows (setq frame-title-format '("ALEC"))) #+end_src 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. #+begin_src emacs-lisp (scroll-bar-mode 0) #+end_src 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. #+begin_src emacs-lisp (tool-bar-mode -1) #+end_src Let the mouse-wheel move the cursor in a sane manner. #+begin_src emacs-lisp (setq mouse-wheel-scroll-amount '(1 ((shift) . 1))) (setq mouse-wheel-progressive-speed nil) (setq mouse-wheel-follow-mouse +1) #+end_src ** File-system management (GUI) Not quite sure where this should go yet. Finder is [fn:dbe73f8c: https://en.wikipedia.org/wiki/Finder_(software)] is just fine (Fine-der?), and the curiosity is still there for an in-Emacs solution. Speedbar [fn:c05b9cba: http://www.emacswiki.org/emacs/SpeedBar] and SrSpeedbar [fn:41a6cbbc: http://www.emacswiki.org/emacs/SrSpeedbar] look nice, as does [fn:8cc3a263: https://github.com/jaypei/emacs-neotree]. 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= [fn:85d63d39: https://github.com/m2ym/direx-el] 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 [fn:4c7d24d1: https://stackoverflow.com/questions/3538064/nerdtree-for-emacs]! What about =eshell=? That doesn't really suit the use case, either. Just watched this [fn:a34be4d5: https://www.youtube.com/watch?v=NKtocCAWxiE] 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. #+begin_src emacs-lisp (require 'neotree) #+end_src ** File-system/directory management (Console) The last file or file-system management tool that I used wast Norton Commander [fn:729276f2: https://en.wikipedia.org/wiki/Norton_Commander] and then Midnight Commander [fn:1cf538c0: https://www.midnight-commander.org/], 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 [fn:b1078e9e: http://www.emacswiki.org/DiredDetails], 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 [fn:7b0e8e3b: https://www.gnu.org/software/emacs/manual/html_node/elisp/Regular-Expressions.html] 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. #+begin_src emacs-lisp (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) #+end_src Try to guess the target directory for operations. #+begin_src emacs-lisp (setq dired-dwim-target t) #+end_src After dabbling, something happened that really changed my mind. These three articles changed everything: [fn:87e72370: http://www.masteringemacs.org/articles/2014/04/10/dired-shell-commands-find-xargs-replacement/] [fn:d82e40f9: http://www.masteringemacs.org/articles/2011/03/25/working-multiple-files-dired/] [fn:fe52afc4: http://www.masteringemacs.org/articles/2013/10/10/wdired-editable-dired-buffers/]. 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): #+begin_src emacs-lisp (require 'find-dired) (setq find-ls-option '("-print0 | xargs -0 ls -ld" . "-ld")) #+end_src 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 #+begin_src emacs-lisp (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) #+end_src 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. #+begin_src emacs-lisp (require 'dired-imenu) #+end_src ** Save history of all things See: [fn:43a849e2: https://www.gnu.org/software/emacs/manual/html_node/emacs/Saving-Emacs-Sessions.html] [fn:ac19c66e: http://fly.srk.fer.hr/~hniksic/emacs/savehist.el] [fn:c39d161c: https://stackoverflow.com/questions/1229142/how-can-i-save-my-mini-buffer-history-in-emacs] 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. #+begin_src emacs-lisp (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))) #+end_src =savehist= configuration follows. #+begin_src emacs-lisp (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) #+end_src ** Spell-checking See: [fn:4fc20d0a: https://www.gnu.org/software/emacs/manual/html_node/emacs/Spelling.html] [fn:b6f544fd: http://www.emacswiki.org/emacs/InteractiveSpell] [fn:e620b160: http://blog.binchen.org/posts/what-s-the-best-spell-check-set-up-in-emacs.html] [fn:8ce1e37a: http://melpa.milkbox.net/#/ac-ispell] 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. #+begin_src emacs-lisp (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) #+end_src So is the personal replacement dictionary. This is a copy and paste of the previous section. It is obviously a candidate for cleanup. #+begin_src emacs-lisp (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) #+end_src ** 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 [fn:88ce9bae: https://github.com/flycheck/flycheck] seems to be the best of the best out there. #+begin_src emacs-lisp (require 'flycheck) (add-hook 'after-init-hook #'global-flycheck-mode) (gcr/diminish 'flycheck-mode) #+end_src ** Templating See: [fn:c3b8f741: https://github.com/capitaomorte/yasnippet] 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. #+begin_src emacs-lisp (require 'yasnippet) #+end_src Remaining configuration follows. #+begin_src emacs-lisp (yas-global-mode 1) (gcr/diminish 'yas-minor-mode) #+end_src =yas= shouldn't use =TAB=. #+begin_src emacs-lisp (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) #+end_src ** White-space management See: [fn:1283938f: https://www.gnu.org/software/emacs/manual/html_node/emacs/Useless-Whitespace.html] Do you need to see tabs and other control characters? Usually, yes. #+begin_src emacs-lisp (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) #+end_src ** Mark and Region When you start typing and text is selected, replace it with what you are typing, or pasting, or whatever. [fn:626951e5: https://www.gnu.org/software/emacs/manual/html_node/emacs/Using-Region.html] #+begin_src emacs-lisp (delete-selection-mode 1) #+end_src ** 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. [fn:0a48462d: http://marmalade-repo.org/packages/diminish] #+begin_src emacs-lisp (require 'diminish) #+end_src The modeline is capable of so many things. Though I use it for few, I value it greatly. Even the generic, optional options [fn:dc1e3869: https://www.gnu.org/software/emacs/manual/html_node/emacs/Optional-Mode-Line.html] are nice. Show the file size. #+begin_src emacs-lisp (size-indication-mode) #+end_src It is nice to see the column number, if you are counting columns (not calories). #+begin_src emacs-lisp (column-number-mode 1) #+end_src 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. #+begin_src emacs-lisp :noweb-ref ignore (setq display-time-format "%R %y-%m-%d") (display-time-mode +1) #+end_src Over time you start to, as which everything else in Emacs, think about configuring it "better". Simple things like the file state indicator [fn:c6a0c2b8: http://ergoemacs.org/emacs/modernization_mode_line.html] 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 [fn:8090ede6: https://github.com/milkypostman/powerline] really got me thinking though just because it is so stunning with the use of XPM [fn:7aca939e: https://en.wikipedia.org/wiki/X_PixMap]. 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 [fn:75606d43: https://github.com/Bruce-Connor/smart-mode-line/] 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 [fn:d5ddabf6: http://www.emacswiki.org/emacs/ModeLineConfiguration] 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. ** 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) [fn:cd3051f0: https://github.com/jschaf/esup] 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=. #+begin_src emacs-lisp (autoload 'esup "esup" "Emacs Start Up Profiler." nil) #+end_src ** Minibuffer You will want to configure this at some point. Make it easier to answer questions. #+begin_src emacs-lisp (fset 'yes-or-no-p 'y-or-n-p) #+end_src It often displays so much information, even temporarily, that it is nice to give it some room to breath. [fn:3e4cb9f3: https://www.gnu.org/software/emacs/manual/html_node/emacs/Minibuffer-Edit.html] #+begin_src emacs-lisp (setq resize-mini-windows +1) (setq max-mini-window-height 0.33) #+end_src Allow recursive commands-in-commands show help me keep track of the levels of recursion. #+begin_src emacs-lisp (setq enable-recursive-minibuffers t) (minibuffer-depth-indicate-mode 1) #+end_src ** Searching / Finding / Replacing [fn:350ccf16: http://repo.or.cz/w/emacs.git/blob_plain/HEAD:/lisp/ido.el] [fn:137: https://github.com/lewang/flx] *** Searching Perhaps an odd topic, but how you handle spaces when performing an interactive search is a choice: #+begin_src emacs-lisp (setq isearch-lax-whitespace +1) (setq isearch-regexp-lax-whitespace +1) #+end_src Make searches case-insensitive. #+begin_src emacs-lisp (setq-default case-fold-search +1) #+end_src *** 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. #+begin_src emacs-lisp (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) #+end_src *** 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. #+begin_src emacs-lisp (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 " => ") #+end_src =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 [[https://github.com/bbatsov/solarized-emacs/blob/master/solarized.el#L526][support]] for Anzu. I don't like it. I could only configure it using Customize. ** 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 [fn:0474d420: http://emacsredux.com/blog/2013/04/21/edit-files-as-root/] out. When I typed in the root password and hit enter I got the error #+begin_example E RET is undefined #+end_example 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 [fn:f1ce823e: https://lists.gnu.org/archive/html/help-gnu-emacs/2005-08/msg00140.html] 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: #+begin_example 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 --- ------- #+end_example In other words, the error occurred between the chair and the keyboard. Of course it did. #+begin_src emacs-lisp (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))))) #+end_src ** Popups If possible, use a better pop-up [fn:002bce83: https://github.com/auto-complete/popup-el] . Pos-tip should help [fn:bd72503b: https://github.com/pitkali/pos-tip]. 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. #+begin_src emacs-lisp (require 'pos-tip) (gcr/on-windows (ignore-errors (pos-tip-w32-max-width-height))) #+end_src 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. [[https://github.com/bbatsov/solarized-emacs/blob/master/solarized.el#L1989][This]] was added to the theme config, but I prefer non-bold colors, so I will leave this for now. #+begin_src emacs-lisp (setq pos-tip-foreground-color "#073642") (setq pos-tip-background-color "#839496") #+end_src ** Intellisense (Auto Completion) [fn:a5ec7f2e: http://cx4a.org/software/auto-complete/] 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 [fn:87ff338a: https://company-mode.github.io/], 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. #+begin_src emacs-lisp (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) #+end_src Auto-completion for .-separated words [fn:ab4081de: https://github.com/tkf/auto-complete-chunk] 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. #+begin_src emacs-lisp (require 'auto-complete-chunk) #+end_src ** Symbolic Expression Management [fn:60c9aa87: https://github.com/Fuco1/smartparens] There are a lot of nice options [fn:f3efaa48: http://www.emacswiki.org/emacs/ParEdit] [fn:65635705: http://www.emacswiki.org/emacs/ElectricPair] [fn:3407e119: https://github.com/rejeep/wrap-region.el] [fn:143: https://code.google.com/p/emacs-textmate/] [fn:2c32e1ab: https://github.com/capitaomorte/autopair]. 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? #+BEGIN_QUOTE I object to doing things that computers can do. #+END_QUOTE 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. #+begin_src emacs-lisp (require 'smartparens-config) (show-smartparens-global-mode +1) (gcr/diminish 'smartparens-mode) (setq sp-show-pair-from-inside nil) #+end_src Recently I learned of [fn:64fbc8ec: https://github.com/promethial/paxedit] Paxedit. "One command /just works/ *everywhere*!". Good to know. Once you get on-board with structural editing, you do, kind of want it /everywhere/. ** Evaluation #+begin_src emacs-lisp (setq-default eval-expression-print-level nil) #+end_src Allow these commands: #+begin_src emacs-lisp (put 'upcase-region 'disabled nil) (put 'downcase-region 'disabled nil) (put 'narrow-to-region 'disabled nil) #+end_src ** 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. #+begin_src emacs-lisp (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)) #+end_src The log edit buffer is only used in VC mode I think, and needs to some configuration. #+begin_src emacs-lisp (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) #+end_src =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. #+begin_src emacs-lisp (defadvice magit-status (before save-before-magit first activate) "Save all buffers before using Magit." (gcr/save-all-file-buffers)) #+end_src Make sure Magit knows that I read the warning. It wasn't instructions. #+begin_src emacs-lisp (setq magit-last-seen-setup-instructions "1.4.0") #+end_src #+begin_src emacs-lisp (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) #+end_src The commit messages are not formatted for all vc providers, so just don't use the default message at all for [[http://debbugs.gnu.org/cgi/bugreport.cgi?bug%3D18954][now]]. #+begin_src emacs-lisp (eval-after-load 'log-edit '(remove-hook 'log-edit-hook 'log-edit-insert-message-template)) #+end_src 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. #+begin_src emacs-lisp (add-to-list 'auto-mode-alist '(".gitignore$" . text-mode)) #+end_src Diminish Magit's auto-revert mode. #+begin_src emacs-lisp (eval-after-load "magit" '(diminish 'magit-auto-revert-mode)) #+End_src ** Command execution helper [fn:e2221a4d: https://github.com/nonsequitur/smex/] 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. #+begin_src emacs-lisp (require 'smex) (smex-initialize) #+end_src Tell =magit= about git working copies that =projectile= knows about [fn:b7cb4360: https://iqbalansari.github.io/blog/2014/02/22/switching-repositories-with-magit/]. #+begin_src emacs-lisp (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))) #+end_src ** Rectangle / Cursors [fn:8d7c694f: https://www.gnu.org/software/emacs/manual/html_node/emacs/Rectangles.html] [fn:178: https://github.com/magnars/multiple-cursors.el] 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 [fn:e9f56c39: http://www.emacswiki.org/emacs/RectangleCommands], 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 [fn:9c0a4159: http://emacsrocks.com/e13.html]. 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. #+begin_src emacs-lisp (require 'multiple-cursors) #+end_src ** 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 [fn:17910758: https://en.wikipedia.org/wiki/Sayre's_law] 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 [fn:c886e5f6: https://github.com/bbatsov/solarized-emacs] 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 \lambda. Based upon the above research, use the DejaVu font family. #+begin_src emacs-lisp (defconst gcr/font-base "DejaVu Sans Mono" "The preferred font name.") #+end_src Months and months and months after that delightful research I was stunned to learn of [fn:6f3a8ca3: http://irreal.org/blog/?p=2828] the [[https://github.com/rolandwalker/unicode-fonts][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. #+begin_src emacs-lisp (require 'unicode-fonts) (unicode-fonts-setup) #+end_src 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 | |---------+---------+-----+---------------------------| | [[http://sourceforge.net/projects/dejavu/files/dejavu/2.34/dejavu-fonts-ttf-2.34.tar.bz2][DejaVu]] | 2.43 | [[http://sourceforge.net/projects/dejavu/files/dejavu/2.34/dejavu-fonts-ttf-2.34.tar.bz2][.]] | Modern classic | | [[http://users.teilar.gr/~g1951d/][Symbola]] | 7.17 | [[http://users.teilar.gr/~g1951d/Symbola.zip][.]] | Neat | | [[http://www.quivira-font.com/][Quivira]] | 4.0 | [[http://www.quivira-font.com/files/Quivira.otf][.]] | Amazing | | [[https://code.google.com/p/noto/][Noto]] | ? | [[http://noto.googlecode.com/git/fonts/individual/hinted/NotoSans-Regular.ttc][1]] [[http://noto.googlecode.com/git/fonts/individual/unhinted/NotoSansSymbols-Regular.ttf][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. #+begin_src emacs-lisp (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)) #+end_src Convert common ASCII values into Unicode representations /for display only/. #+begin_src emacs-lisp (require 'pretty-mode) #+end_src 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! #+begin_src emacs-lisp (setq make-pointer-invisible +1) #+end_src Load font utilities when on a GUI. #+begin_src emacs-lisp (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)) #+end_src ** Project management [fn:7a558748: http://batsov.com/projectile/] 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. #+begin_src emacs-lisp (projectile-global-mode 1) (gcr/diminish 'projectile-mode) #+end_src ** Emacs Speaks Statistics (ESS) [fn:3bba0c0c: http://ess.r-project.org/] [fn:25441790: https://en.wikipedia.org/wiki/Emacs_Speaks_Statistics] [fn:a2ae633d: http://www.emacswiki.org/emacs/EmacsSpeaksStatistics] [fn:b28cb112: http://blog.revolutionanalytics.com/2011/08/ess.html] [fn:353ffc35: http://blog.revolutionanalytics.com/2014/03/emacs-ess-and-r-for-zombies.html] [fn:3b20a6da: https://rstudio-pubs-static.s3.amazonaws.com/2246_6f220d4de90c4cfda4109e62455bc70f.html] This section takes about 15 seconds to tangle. Get =ESS= loaded before doing anything with it in here or out there. #+begin_src emacs-lisp (require 'ess-site) #+end_src For a minimalist release history, read the news file [fn:7be08525: http://ess.r-project.org/Manual/news.html]. For a brief, brief overview and release history, read the readme [fn:1b644ec0: http://ess.r-project.org/Manual/readme.html]. For a comprehensive overview, read the manual [fn:adfd9a4c: http://ess.r-project.org/Manual/ess.html]. 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=. #+begin_src emacs-lisp (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) #+end_src ℝ 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. #+begin_src emacs-lisp (setq ess-eldoc-show-on-symbol t) #+end_src 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 #+begin_src emacs-lisp (setq ess-use-tracebug t) #+end_src 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. #+begin_src emacs-lisp (setq ess-tracebug-search-path '()) #+end_src - Make error navigation simpler #+begin_src emacs-lisp (define-key compilation-minor-mode-map [(?n)] 'next-error-no-select) (define-key compilation-minor-mode-map [(?p)] 'previous-error-no-select) #+end_src - The font size for watched variables. #+begin_src emacs-lisp (setq ess-watch-scale-amount -1) #+end_src 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= #+begin_src emacs-lisp (setq ess-describe-at-point-method 'tooltip) #+end_src - Visualize just about anything. - =ess-R-object-popup= #+begin_src emacs-lisp (require 'ess-R-object-popup) #+end_src - Rdired is another way to work with object - =ess-rdired= - View, delete, plot, and update buffer (ala /revert/) are single key commands #+begin_src emacs-lisp (autoload 'ess-rdired "ess-rdired") #+end_src - Visualize data frames better. - =ess-R-dv-ctable= - =ess-R-dv-pprint= #+begin_src emacs-lisp (require 'ess-R-data-view) #+end_src - inlineR - /Not/ a competitor to =org-mode= - Ultra lightweight LP, really #+begin_src emacs-lisp (require 'inlineR) #+end_src 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 [fn:8dece4ca: https://stat.ethz.ch/pipermail/ess-help/2014-January/009705.html]. That is totally fine with me, that is really the best way to load stuff. Out of curiosity, I read more about it here [fn:c5cac42b: https://github.com/milkypostman/melpa/issues/6], 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 [fn:9039b33e: https://google-styleguide.googlecode.com/svn/trunk/Rguide.xml] [fn:da0df786: http://adv-r.had.co.nz/Style.html]. The simple (dumb) part of me suspects that C++ formatting is generally just fine [fn:5b466d0c: https://stackoverflow.com/questions/7502540/make-emacs-ess-follow-r-style-guide]. 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. #+begin_src emacs-lisp (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) #+end_src Since I'm using ℝ for everything, configure /everything/ to be using ℝ. #+begin_src emacs-lisp (setq inferior-ess-program "R") (setq inferior-R-program-name "R") (setq ess-local-process-name "R") #+end_src Always start =ess= within the curent =emacs= frame, it doesn't need to be separate. #+begin_src emacs-lisp (setq inferior-ess-same-window nil) (setq inferior-ess-own-frame nil) #+end_src Help buffers all belong in the same frame. #+begin_src emacs-lisp (setq ess-help-own-frame nil) #+end_src 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. #+begin_src emacs-lisp (setq ess-ask-for-ess-directory nil) #+end_src 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. #+begin_src emacs-lisp (setq inferior-ess-exit-command "q('no') ") #+end_src When commands are executed, display their output within the current buffer, rather than to a new dedicated buffer for them. #+begin_src emacs-lisp (setq ess-execute-in-process-buffer +1) #+end_src 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. #+begin_src emacs-lisp (setq ess-switch-to-end-of-proc-buffer t) #+end_src Use typical auto completion in buffers here, but don't do it when the next char is a symbol or closed paren. #+begin_src emacs-lisp (setq ess-tab-complete-in-script +1) (setq ess-first-tab-never-complete 'symbol-or-paren-or-punct) #+end_src Use =ido= completion whenever possible. #+begin_src emacs-lisp (setq ess-use-ido t) #+end_src Handle rdoc and rmd files, though I have never used them… yet. #+begin_src emacs-lisp (add-to-list 'auto-mode-alist '("\\.rd\\'" . Rd-mode)) (add-to-list 'auto-mode-alist '("\\.Rmd$" . r-mode)) #+end_src 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. #+begin_src emacs-lisp (setq ess-use-eldoc t) (setq ess-eldoc-show-on-symbol t) (setq ess-eldoc-abbreviation-style 'normal) #+end_src Make it really easy to search the ℝ archives for anything. #+begin_src emacs-lisp (local-set-key (kbd "C-c C-. S") 'ess-rutils-rsitesearch) #+end_src Make it really easy to do common stuff for ℝ with good keybindings. #+begin_src emacs-lisp (require 'ess-rutils) (setq ess-rutils-keys +1) #+end_src =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. #+begin_src emacs-lisp (require 'r-autoyas) (setq r-autoyas-debug t) (setq r-autoyas-expand-package-functions-only nil) (setq r-autoyas-remove-explicit-assignments nil) #+end_src 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. #+begin_src emacs-lisp (setq ess-ac-R-argument-suffix "=") #+end_src When I started to standardize arrows across modes, I recalled the =ess= documentation and was also reminded [fn:645cef99: http://www.r-bloggers.com/a-small-customization-of-ess/] here how easy it is to customize it. Not sure where I put the notes, but long ago I researched the ℝ coding standards. [[http://stackoverflow.com/questions/7502540/make-emacs-ess-follow-r-style-guide][This post]] by Eddelbuettel led me to believe that the ℝ [[http://cran.r-project.org/doc/manuals/R-ints.html#R-coding-standards][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. #+begin_src emacs-lisp (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) #+end_src #+begin_src emacs-lisp (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) #+end_src This [fn:1ffa40c2: http://www.r-bloggers.com/a-small-customization-of-ess/] 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. #+begin_src emacs-lisp (setq ess-keep-dump-files +1) #+end_src =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. #+begin_src emacs-lisp (setq ess-delete-dump-files nil) #+end_src 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. #+begin_src emacs-lisp (setq ess-mode-silently-save +1) #+end_src 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". #+begin_src emacs-lisp (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)) #+end_src 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. #+begin_src emacs-lisp (setq inferior-R-args "--no-save --no-restore") #+end_src 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 [fn:32fe93bc: http://www.emacswiki.org/emacs/ESSAutoParens] handles brackets, indentation quite well [fn:5f2adfb8: http://emacs.1067599.n5.nabble.com/indentation-not-working-if-parentheses-are-already-closed-td283806.html] but doesn't provide the behavior that I want. This post [fn:47104806: https://stackoverflow.com/questions/18420933/enabling-mode-specific-paren-indentation-in-emacs-prelude] 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 [fn:cd67477f: https://github.com/Fuco1/smartparens/issues/80], 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 [fn:2c7c401d: https://github.com/bbatsov/prelude/issues/374]. This is a nice generalizable approach that should serve me well for just about everything in this solution-area. Here [fn:5a732a42:: https://github.com/rdallasgray/graphene/blob/master/graphene-smartparens-config.el] is a post showing a more advanced usage that handles context which is nice to know is an option. #+begin_src emacs-lisp (sp-local-pair 'ess-mode "{" nil :post-handlers '((gcr/indent-curly-block "RET"))) #+end_src =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 [fn:2fbb65bd: https://stackoverflow.com/questions/2770523/how-can-i-background-the-r-process-in-ess-emacs]. 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. #+begin_src emacs-lisp (setq ess-eval-visibly 'nowait) #+end_src 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. #+begin_example (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))) #+end_example ** Org This section takes about 15 seconds to tangle. *** 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 [fn:40a1962e: http://orgmode.org/manual/Speed-keys.html#Speed-keys] [fn:d064d3d8: http://notesyoujustmightwanttosave.blogspot.com/2011/12/org-speed-keys.html]. 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= [fn:20c464a3: http://orgmode.org/manual/Clean-view.html#Clean-view], 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 [fn:d58f4050: http://home.fnal.gov/~neilsen/notebook/orgExamples/org-examples.html] 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 [fn:49c014be: http://orgmode.org/manual/JavaScript-support.html]. 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 [fn:0276223e: https://github.com/koddo/org-clock-statusbar-app] this is nice to know of. *** Configuration For this feature to work, it must come /before/ any =org= load statements #+begin_src emacs-lisp (setq org-list-allow-alphabetical +1) #+end_src **** 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>. #+begin_src emacs-lisp (require 'org) (require 'ox-beamer) (require 'ox-md) (require 'htmlize) #+end_src Exports to Confluence are very very helpful. #+begin_src emacs-lisp (require 'ox-confluence) #+end_src =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. #+begin_src emacs-lisp (setq htmlize-output-type 'inline-css) (setq org-html-htmlize-output-type htmlize-output-type) #+end_src =org-show= need special handling, see the install for details. #+begin_src emacs-lisp (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))) #+end_src 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? #+begin_src emacs-lisp (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) #+end_src Make sure that exported files are Unicode UFT-8. #+begin_src emacs-lisp (setq org-export-coding-system 'utf-8) #+end_src Do not preserve line-breaks when exporting instead let the destination format handle it as it sees fit. #+begin_src emacs-lisp (setq org-export-preserve-breaks nil) #+end_src My personal TODO workflow is pretty tame, and it is defined below. #+begin_src emacs-lisp (setq org-todo-keywords '((sequence "TODO" "IN-PROGRESS" "WAITING" "REVIEW" "DONE"))) #+end_src When running in a GUI, I would like linked images to be displayed inside of Emacs. #+begin_src emacs-lisp (setq org-startup-with-inline-images (display-graphic-p)) #+end_src When exporting anything, do not insert the exported content intto the kill ring. #+begin_src emacs-lisp (setq org-export-copy-to-kill-ring nil) #+end_src Use =ido= completion in =org=. #+begin_src emacs-lisp (setq org-completion-use-ido +1) #+end_src =org= lets you use single letter commands to do stuff on headers. I like to use =c= for cycling the header expansion. #+begin_src emacs-lisp (setq org-use-speed-commands +1) #+end_src Ask before execution of shell links. This may look inconsistent given that I allow evaluation. It just looks inconsistent. #+begin_src emacs-lisp (setq org-confirm-shell-link-function 'y-or-n-p) #+end_src Ask before execution of emacs-lisp links. This may look inconsistent given that I allow evaluation. It just looks inconsistent. #+begin_src emacs-lisp (setq org-confirm-elisp-link-function 'y-or-n-p) #+end_src Make sure that incomplete TODO entries prevent the enclosing parent from every turning to DONE. #+begin_src emacs-lisp (setq org-enforce-todo-dependencies +1) #+end_src Allow the mouse to do =org= things like expand and collapse headings. #+begin_src emacs-lisp (gcr/on-gui (require 'org-mouse)) #+end_src Use unicode characters to visualize things like right arrow eg \rarr. #+begin_src emacs-lisp (setq org-pretty-entities +1) #+end_src Use a real ellipsis to render an ellipsis for =org= stuff like showing that a header is collapsed. #+begin_src emacs-lisp (setq org-ellipsis "…") #+end_src 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. #+begin_src emacs-lisp (setq org-hide-leading-stars +1) #+end_src Display emphasized text as you would in a WYSIWYG editor. #+begin_src emacs-lisp (setq org-fontify-emphasized-text +1) #+end_src 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 #+begin_src emacs-lisp (setq org-highlight-latex-and-related '(latex script entities)) #+end_src There is an auto-complete provider for org-mode [fn:a94049d3: https://github.com/aki2o/org-ac]. 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: #+begin_src emacs-lisp (require 'org-ac) (org-ac/config-default) #+end_src Footnote management is an important topic. Thanks to Richard [fn:44cb98d6: https://lists.gnu.org/archive/html/emacs-orgmode/2014-04/msg00172.html], there is a concise approach for this, which I've pasted here: #+begin_example 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 #+end_example #+begin_src emacs-lisp (setq org-footnote-define-inline +1) (setq org-footnote-auto-label 'random) (setq org-footnote-auto-adjust nil) (setq org-footnote-section nil) #+end_src 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: #+begin_src emacs-lisp (setq org-catch-invisible-edits 'error) #+end_src Though I am not deliving deep, it is hard not to want to customize some stuff and perhaps this is the start: #+begin_src emacs-lisp (setq org-loop-over-headlines-in-active-region t) #+end_src 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. #+begin_src emacs-lisp (setq org-export-with-toc nil) #+end_src 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. #+begin_src emacs-lisp (setq org-startup-folded "nofold") #+end_src 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=. #+begin_src emacs-lisp (setq org-image-actual-width t) #+end_src Hide the delimeter for emphasized text. This may break table alignment. #+begin_src emacs-lisp (setq org-hide-emphasis-markers +1) #+end_src Realign tables automatically. #+begin_src emacs-lisp (setq org-startup-align-all-tables +1) #+end_src **** 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 [fn:edec422c: https://lists.gnu.org/archive/html/emacs-orgmode/2014-07/msg00309.html] discussion and Nick Dokos agreed here that [fn:32dff2df: http://article.gmane.org/gmane.emacs.orgmode/88741] that it is the ideal approach because it does /not/ interfere with export. This thread [fn:5863d9db: https://lists.gnu.org/archive/html/emacs-orgmode/2015-01/msg00534.html] explained the correct approach as of <2015-01-22 Thu>, which meant a simpler function call. #+begin_src emacs-lisp (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) #+end_src Load the =ob-sml= package. Perhaps some day it will end up in the mainline. #+begin_src emacs-lisp (require 'ob-sml nil 'noerror) #+end_src Tell =org= that it may evaluate all of the listed languages. #+begin_src emacs-lisp (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))) #+end_src 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. #+begin_src emacs-lisp (setq org-babel-use-quick-and-dirty-noweb-expansion nil) #+end_src You may display syntax highlighting for code in source blocks. I don't. #+begin_src emacs-lisp (setq org-src-fontify-natively nil) #+end_src 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. #+begin_src emacs-lisp (setq org-src-preserve-indentation +1) #+end_src 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. #+begin_src emacs-lisp (setq org-edit-src-content-indentation 0) #+end_src When edit mode is exited, the option exists to automatically remove empty opening and closed lines for the source block. Never do this. #+begin_src emacs-lisp (setq org-src-strip-leading-and-trailing-blank-lines nil) #+end_src For code blocks that I use a *lot*, add templates for source blocks because my current approach is to do a =\n?\n")) #+end_src 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. #+begin_src emacs-lisp (mapc (lambda (asc) (let ((org-sce-dc (downcase (nth 1 asc)))) (setf (nth 1 asc) org-sce-dc))) org-structure-template-alist) #+end_src It looks like ℝ is going to be another one, but don't process it to downcase it… order matters here. #+begin_src emacs-lisp (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" "")) #+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. #+begin_src emacs-lisp (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: <" (format-time-string "%Y-%m-%dT%T%z") ">"))) #+end_src Sacha implemented a nice feature to export Unicode checkboxes correctly from =org=. That will get into the release. Use the workaround and warn when it is no longer needed. Now it is in the release. Thanks Sacha and =org= team! #+begin_src emacs-lisp (setq org-html-checkbox-type 'unicode) #+end_src Before exporting to PDF, save all buffers to make sure that everything is a known good state. #+begin_src emacs-lisp (defadvice org-latex-export-to-pdf (before org-latex-export-to-pdf-before activate) (gcr/save-all-file-buffers)) #+end_src There is a performance issue with tangling when header property inheritance is enabled. Eric explained that [fn:419e4704: https://lists.gnu.org/archive/html/emacs-orgmode/2014-06/msg00719.html] there may be performance gains if some of the header properties are not considered. The list below defines what will be allowed, and everything else will be removed.: #+begin_src emacs-lisp (let* ((allowed '(exports file noweb noweb-ref session tangle)) (new-ls (--filter (member (car it) allowed) org-babel-common-header-args-w-values))) (setq org-babel-common-header-args-w-values new-ls)) #+end_src When source blocks are evaluated, their results get stored in a result area, typically for display. If the results are small, they are displayed with colons instead of an =example= block. My preference is to *always* place them in an example block. #+begin_src emacs-lisp (setq org-babel-min-lines-for-block-output 0) #+end_src I've got auto-save enabled for every buffer that has a file attached to it so I rarely every think about saving a file. When you edit source code in =org-mode= though and do it in a major-mode buffer for that code, =auto-complete= doesn't apply because it isn't associated with a buffer. The following turns on auto- save from this buffer back to the source =org= document. This value is aggressively set to 1 because sometimes in haste you switch out of an =org= edit buffer and then want to get back into it, and if you changes in it are not saved they can be destroyed. You are asked if =Emacs= should, but it is not always obvious why it shouldn't. #+begin_src emacs-lisp (setq org-edit-src-auto-save-idle-delay 1) #+end_src The source editing buffer may be configured to appear in a few different places. For a while I really liked =reorganize-frame= because sometimes you want to be able to see the code you are editing in edition to the rest of the document. At least that is what I am telling myself. Once I learned you could changed it I realized that 1 I should have asked if it could be changed and 2 I should have changed it. #+begin_src emacs-lisp (setq org-src-window-setup 'current-window) #+end_src When you evaluate code its results are inserted into a =RESULTS= block by default. The documentation indicates though that you may instead use a name if the source block has a name, or a cache-id. In either case, both seem to be better options for traceibility. #+begin_src emacs-lisp (setq org-babel-results-keyword "NAME") #+end_src =org= has a really nice feature that hitting =C-c C-c= will generally just do the /right thing/. It is really nice. That feature extends to source blocks of course. Ironically I had a typo here, typing /of curse/ instead of /of course/. The thing is that you really, really need to develop a personal workflow, and then configure the tool to enable it. The more I learn about =org=, the more leery I am about making it really easy to evaluate code. I want it to be a really, really specific and decided action to evaluate a code block, so don't make it so easy as =C-c C-c=. #+begin_src emacs-lisp (setq org-babel-no-eval-on-ctrl-c-ctrl-c +1) #+end_src =org= already uses the guillemet [fn:086b7602: https://en.wikipedia.org/wiki/Guillemets] for demarcating noweb references, but it does it using the work-around of just using less-than and greather-than characters twice. That is fine. Because Emacs supports Unicode just fine though, tell =org= to use the real symbol. #+begin_src emacs-lisp (setq org-babel-noweb-wrap-start "«") (setq org-babel-noweb-wrap-end "»") #+end_src My preference is to rely upon heading property inheritance to define source block names. That way, you can just do your work knowing "where" you are working and keep it simple by not having to name everything. That was just fine until I wrote a document where I needed to name each source block. It gets easy to forget the source block’s name. Not the end of the world, but very nice to know. #+begin_src emacs-lisp (defun gcr/org-edit-src-code-plus-name () "Edit the well-described source code block. Attribution: URL `https://lists.gnu.org/archive/html/emacs-orgmode/2014-09/msg00778.html'" (interactive) (let* ((eop (org-element-at-point)) (name (or (org-element-property :name (org-element-context eop)) "ॐ")) (lang (org-element-property :language eop)) (buff-name (concat "*Org Src " name "[" lang "]*"))) (org-edit-src-code nil nil buff-name))) #+end_src It would be nice to be able to use =vc-next-action= when editing source blocks in the source block edit buffer. Those buffers are new buffers that get the contents of the source block copied into them, the mode gets loaded, and additional hooks for this special org mode source editing are run. When editing is complete, the contents of that buffer are copied back into the source block, the original contents are removed, and the new ones are inserted. I wasn't sure how to proceed with this and asked the list. Aaron Ecay explained how to simply close the buffer first. That is a nice approach because everything will be as close to normal operational procedures as possible. Jonathan Leech-Pepin showed how to get a handle on the source buffer, and execute some code in the context of /that/ buffer. In this case it would mean executing the commit action inside of the backing buffer. Both are great options, and I am having trouble with both of them. The former is great because it is exactly how you would do it now. The latter is great because you would *not* be interrupted with the source block buffer being closed. At this point, I've only got the former working so that is where I will start. #+begin_src emacs-lisp (defadvice vc-next-action (before vc-next-action-in-org-src-block last activate) "If in org source block, exit it." (when (condition-case nil (org-src-in-org-buffer) (error nil)) (org-edit-src-exit))) #+end_src Not sure where to note this, but I do need to do it somewhere: #+begin_quote - babel, document my two modes of use as eval everything and store the results, replacing them, which is good for documents that use that data, and then the style I just did for homework which did ":results output silent" when the intent was more very close to coding, and ultimately using the code to deliver the consumable product #+end_quote Thank you Nicolas Goaziou [fn:486109d1: https://lists.gnu.org/archive/html/emacs-orgmode/2014-11/msg00776.html], for the beginnings of an =org-lint=. The goal here was to: 1) Report an error if there is a source block without a language specified 2) Report an error if there is a source block with a language specified that is *not* present in `org-babel-load-languages' And, it does. #+begin_src emacs-lisp (defun gcr/src-block-check () (interactive) (org-element-map (org-element-parse-buffer 'element) 'src-block (lambda (src-block) (let ((language (org-element-property :language src-block))) (cond ((null language) (error "Missing language at position %d" (org-element-property :post-affiliated src-block))) ((not (assoc-string language org-babel-load-languages)) (error "Unknown language at position %d" (org-element-property :post-affiliated src-block))))))) (message "Source blocks checked in %s." (buffer-name (buffer-base-buffer)))) #+end_src In [[https://emacs.stackexchange.com/questions/7844/org-mode-have-flycheck-resolve-relative-config-while-editing-code-blocks][this]] post, the author explains how he would source block buffers to appear to have a file name so that FlyCheck can do its thing correctly. It is really simple. I have not thorougly tested it. I tested it once. #+begin_src emacs-lisp (defadvice gcr/org-edit-src-code-plus-name (around set-buffer-file-name activate compile) (let ((file-name (buffer-file-name))) ad-do-it (setq buffer-file-name file-name))) #+end_src Why isn't this code documented? I replaced it with =gcr/org-edit-src-code-plus-name=. #+begin_src emacs-lisp (setq org-edit-src-code nil) #+end_src ***** Core Babel Configuration ****** Comments [fn:1e1a7e1f: http://orgmode.org/manual/comments.html#comments] There is always a question of how to instill traceability in your artifacts. org provides =:comments= for that. Tangling with that value set to =link=, for example, would add a prefix and postfix comment to the tangled file with the name of the header from which the generated file was tangled. When I tangle the .emacs.el, then it puts something like this for that: #+begin_quote ~;; [[file:~/git/bitbucket-grettke/home/TC3F.org::*Fully%20Loaded%20System][Fully\ Loaded\ System:1]]~ file contents go here ;; Fully\ Loaded\ System:1 ends here #+end_quote When you follow the link, it will take you right back to the block that specified the tangling of the document. That is a start, though not super for tracking down details of where the code snippets really originated down to the source blocks themselves. Trying to understand the other settings, I found =both= to look like this: #+begin_quote ;; Fully Loaded System ;; Convert decisions into a runnable system. ~;; [[file:~/git/bitbucket-grettke/home/TC3F.org::*Fully%20Loaded%20System][Fully\ Loaded\ System:1]]~ file contents go here ;; Fully\ Loaded\ System:1 ends here #+end_quote =noweb= looks like, well I'm going to put a couple examples, because this is the best setting. This provides was 99% of org mode literate programmers want which is traceability back from every tangled piece of code to the original document. #+begin_quote ;; [[file:~/git/bitbucket-grettke/home/TC3F.org::*Windows%20%5Bfn:38%5D][nil]] ;; [[file:~/git/bitbucket-grettke/home/TC3F.org::*Windows%20%5Bfn:38%5D][nil]] ;; [[file:~/git/bitbucket-grettke/home/TC3F.org::*Frames%20%5Bfn:46%5D][nil]] #+end_quote After all of this research, I found that doing noweb-ref tangling, the source locations are not included, so it is no very useful to include comments, and I removed them, at least for now. I am not sure how I want to use them right now. The type of information that you provide as meta-data is up to you and depends upon your mental model for your org document. My mental model is mostly to use headings as the logical area for addressing a particular /concern/ satisfied by that portion of my Emacs configuration, so the tangling comments reflect that. In other words, in this document at least, I rarely name source blocks because the header name is the "true name", and closing the tangle comment with the source block name is really confusing because it usually is =nil=. The org links are fine, too, because they convey all of the necessary information whether you are using org or not. It is more likely that most readers will not use org links, so they come second. As it happens, that didn't really work out as I had hoped. The =link= style works, and =noweb= does not. Not sure why and not digging further, so sticking with that. Also, I had customized the links, and did that incorrectly, so I removed those, too. When Eric said that one part of it wasn't implemented, I didn't to dig into what was working anymore than I had already because it has already been many hours invested. Now I've got weeks invested and I'm shocked to find that using links in the tangled file is worse then useless, it is actually harmful. It just doesn't help, atleast in the sytems that I am tangling. As such I am no longer using it. <2014-11-02 Sun> Well, just read a post of another person using it (many months after I retired it), and I think that I want to try keeping it around. My problem was probably between my keyboard and chair so I will give it another go. #+begin_src emacs-lisp (gcr/set-org-babel-default-header-args :comments "noweb") #+end_src ****** Results [fn:1625d11f: http://orgmode.org/manual/results.html#results] Always display results like you would seem them in a REPL. #+begin_src emacs-lisp (gcr/set-org-babel-default-header-args :results "output replace") #+end_src ****** Exports [fn:7dad95aa: http://orgmode.org/manual/exports.html#exports] Export both code blocks and results in exports. #+begin_src emacs-lisp (gcr/set-org-babel-default-header-args :exports "both") #+end_src ****** Noweb [fn:3da67e2d: http://orgmode.org/manual/noweb.html#noweb] Expand noweb references before the block is tangled or evaluated, but exported. This embraces the notion that you are telling the right thing to the computer and the right thing to the human. This is the only proper setting to do so. #+begin_src emacs-lisp (gcr/set-org-babel-default-header-args :noweb "no-export") #+end_src ****** Padline [fn:508104fc: http://orgmode.org/manual/padline.html] Deals with inserted code blocks and whether or not you havep padding around them. For a while I liked that, to make it easier to see. Then I used comments to make it clear, but I may or may not use them. Finally, I decided that not to make it easier for that form of the code to read for humans, because that is what the LP document is for. <2014-11-02 Sun> After doing that, which totally made sense, I decided to give tangle comments a go again, and although we are still generating for a computer, it can be nice when =de-tangling= to have some space. <2015-03-29 Sun> Reading the documentation, I see that this setting is required for =org-babel-tangle-jump-to-org= to work. #+begin_src emacs-lisp (gcr/set-org-babel-default-header-args :padline "yes") #+end_src ****** Eval [fn:f6ab36a6: http://orgmode.org/manual/eval.html#eval] This is probably the single most important configuration parameter for your document's source blocks. Initially, that value is obscured by the need to configure the rich variety of other options though, and this parameter is often visited during the second eighty percent of your investment in =org-babel= when you are "in the thick" of it. Still trying to make sense of it all myself, I am adhering to a lightweight user-story driven configuration of this feature, as I believe that it is the only way that it will make sense to me. The key goal here for me is to: - Define typical usage scenarios - Identify key traits - Realize those traits in my workflow The current configuration is more like: - Default allows for super fast code execution messages storing the results - Any form of reproducibl research including for example a tiny, tiny bit of code necessary to get a =knitr= like setup =:header-args: :results output silent= ******* Story A: Messages 20% of my time spent composing email or mailing list messages. Those messages may be composed of plain text with some nice markup. They also might have references and citations. The big value comes with superb code block definition and execution facilities. Those messages are short-lived; they are never stored in =git= and unlikely to even end up on the file-system. My work-flow here is: - Compose the =org= document - Prepare necessary buffers for code evaluation, or not, intentionally - Execute (weave) source blocks and store the results within the document - Export to the destination format ******* Story B: Notes 40% of my time is spent taking notes. It is so delightful to do so here. A lot of those notes are for programming languages so the workflow is nearly identical to =A=. The actions for navigating among source blocks is used all of the time to quickly navigate the document's source code, reflecting more thoughtfulness while working with the document. There is more concern here, because the document is stored in =git= and long-lived, it will be published many times. An important approach here is that I like to make a clear and concise distinction of the responsibilities of tangling and exporting because I don't like surprises. I want to know how source blocks results were generated, and when, as well as details about the export itself. This is a scope restriction that opens up space to make better sense of the workflow of the document itself. At its simplest, I just want to see a date-time showing when the document was published for example. My workflow here is: - Compose the =org= document - Prepare necessary buffers for code evaluation, or not, intentionally - Execute (weave) source blocks and store the results within the document - Export to the destination format - Evaluate in-line source code relevant to that particular exportation ******* Story C: Documents 40% of my time is spent managing documents. In my case, it is this document. There are others, but they are minute in comparison. This is the storehouse, proving ground, and production deployment environment for every though, idea, dream, and goal that I can come up with in regards to TC3F. It shares the same traits as =A= and =B=, and adds many more. The first addition is the utilization of =no-web= to tangle source code and also tangle executable source code. The document evolution has relied heavily upon this feature. It has allow amazing flexibility. It is so critical that it must always be available. The second addition is a different scope of concern. My desire to make the tangling and exportation of this document is to have it more controlled. Unsure, I waver between restricting evaluation of code blocks by default and enabling over the entire document and simply allowing it globally. I don't like accidentally evaluating source blocks and getting their results, but I suppose that I may rely upon my commits to reveal my error. I suppose that my big takeaway here is that I want it simple, and want to be able to lock things down if necessary. ******* Study Studying the scenarios, the desires seem clear. There is a combination of agility and scope that ought to make productivity go up. The essence may be better expressed in terms of responsibilities based upon my preferences expressed above: - A document is responsible for - Defining source blocks - Configuring their execution environments - Displaying their results - Execution of this document is responsible for - Evaluating source blocks - Collecting results of evaluation - Tangling is responsible for combining source blocks - In this file - For output blocks - For inclusion in source definitions used in function calls - In a new file - Exporting is responsible for - Converting this document to a new presentation format - Only in-line source blocks may be evaluated during exploration - Be explicit about the difference eg - Execution results as stored in the document - Exportation results are stored in the export document - Key difference for people to make sense of things ******* Preface to Tooling The next task is to convert the studies desired into a configuration to realize them. At first blush the configuration options will seem confusing. The best approach is to "play" with the configurations to learn and finalize your approach. That is how I ended up with this configuration. All of the configuration it based upon that combination of need and desire and how the system itself works. At best, it will only make sense in this context. Over time, it will make more sense. That period of evolution and growth is reflected in the =org= documentation itself for example when you read about =ditaa= in regards to exporting [fn:14fb5203: http://orgmode.org/manual/Exporting-code-blocks.html]. The more familiar and comfortable with =org= one becomes, the more sense mentions such as that make. ******* A More Concise Goal (Making Sense of Things) This facilitate my personal model for =LP= with org for evaluation modes. There are only two of them, =A= and =B=. Mode =A= allow execution to occur where the results are likely to be captured within the document. The single responsibility of that mode is to perform and capture the entirety of the computation. That really sums it up. All computation is done here because it is time and context sensitive. The document in that form will serve as a snapshot in time. If you run ℝ code then capture the results and plots and also the version of itself and the packages used. If you have versioned links for your data set, then report it here. Think of future users of your research as archeologists trying to piece together what you did; you should make their job really easy. This is a self contained computational unit, and its results, too. Include everything that matters for your computation. Consider Vagrant [fn:28698f18: http://www.vagrantup.com/] regardless of how much slower it may run on a virtual. How you defined this document and computed it and captured the results are all *one* thing that needs to both be considered and captured in its entirety. Mode =B= is a little simpler. All of the hard work has been done. Everything just mentioned has been done. This is purely responsible for publishing. Perhaps you want to submit it to a journal, that is publishing. Perhaps you want to post it on a blog, that is publishing. Publishing has different concerns. You want to know about the environment used to perform the publishing, like the tools and the time. Perhaps you want to more about the computer is was published on. All of those aspects unique to that even of publishing should be included during export. The operator really needs to get on-board with the idea of computational artifacts vs reporting artifacts. For example if you execute mode =A= then you need to store all of its generated artifacts. That includes data, but also graphics that you reference in the document itself. Hopefully you are questioning my claim here. You should! You area asking "Why should I when if I can reproduce the results?!". Great question. The answer only makes sense according to the philosophy I am embracing. Mode =A= defines both the computational unit and its constituent output. That is a single /thing/, a single /thing document/. Now that I am writing this, I am having questions about my claim here, and I will explore them as my understanding is bettered. For now, I am sticking with this because for example I know that I can use PNG anywhere. Well, questions arise because I am unsure how I would publishing to the web without re-generating SVG output vs PNG for web vs PS for LaTeX. Definitely something I will need to explore and for now I am sticking with the plan. Just had lunch and reflected upon the fact that there is clearly distinction between the results of your computation and how you wish to present them, and when. My feeling is that my approach is acceptable in that the computation and generation of summary results is definitely a separate goal from providing it in a particular publishing format and surely more experience needs to be accumulated here. Perhaps the simplest thing to do for greater flexibility is to: - In =A= - Perform the computation - Capture the results of the computation - Produces images and so forth - In =B= - Convert to a new format - Perhaps utilize the results of computation to present differently The key questions are: - May you? - Yes you may - Should you? - Perhaps - It seems easier to separate concerns into computation and presentation That is why evaluation is available on export, to capture aspects unique of export itself, and *not* of the computation. To realize this, the operator must be very thoughtful and aware of the execution model of the document. As it stands, you may separate the time of execution of code blocks and also their results. This is a subtle yet hugely important idea. You may utilize this feature and idea anyway you please, but I will use it a certain way. All computational evaluation and results storage will occur for source blocks in =A=. That is the goal. However, we do not want that to occur for in-line source blocks in mode =A=. That is possible and doable. This will make it easy for the operator of the d document to *see* the difference between code is for =A= versus =B= because the latter will never have its results stored within the source document. A strict separation between the =A= and =B=, roughly computation and export, must be maintained. It is the only way to make sense of how to use =org= as a tool here. One mode is responsible for computation, and the other is responsible for reporting. All of the following configuration is performed in order to realize this goal of A:computation vs B:publishing (exporting). ******* Putting the Pieces Together Make it crystal clear that if the operator wants to evaluate source blocks then she may do so. It is a fundamental right of every =org= mode user and the default configuration shall allow it. If she wants restrictions, then they may easily be added to the document itself. #+begin_src emacs-lisp (setq org-confirm-babel-evaluate nil) (gcr/set-org-babel-default-header-args :eval "always") #+end_src Separate evaluation into two distinct phases or modes that of =A= for computation and =B= for presentation/publishing/exportation (still unsure of the best name given the existing terms both inside and outside of =org=). During exportation, only evaluate inline source blocks. #+begin_src emacs-lisp (setq org-export-babel-evaluate 'inline-only) #+end_src During exportation, evaluate the blocks and replace the source blocks with the resulting value. This gives you exactly what you would expect; the documents look like plain old documents because they are exactly that. #+begin_src emacs-lisp (gcr/set-org-babel-default-inline-header-args :eval "always") (gcr/set-org-babel-default-inline-header-args :results "value replace") #+end_src ****** ℝ Specific Always use the current ℝ session for evaluation. #+begin_src emacs-lisp (gcr/set-org-babel-default-header-args:R :session "*R*") #+end_src Then I read this [fn:16e26884: http://comments.gmane.org/gmane.emacs.orgmode/32814]. *WOW*. That is worth another millions bucks for Eric's prolific contribution to humanity with org-babel. **** KOMA-Script I enjoy writing letters. I enjoy reading letters. LaTeX produces letters that are easy to print and read. Org provides a [[http://orgmode.org/worg/exporters/koma-letter-export.html][KOMA Script exporter]] for [[https://www.ctan.org/pkg/koma-script?lang%3Den][koma-script]]. The Org documentation mentions that the user should read the [[http://orgmode.org/cgit.cgi/org-mode.git/plain/contrib/lisp/ox-koma-letter.el][ox-koma-letter.el]] header documentation. The [[https://www.ctan.org/pkg/babel?lang%3Den][babel]] packages is mentioned in the Org documentation. The package documentation explains that it should be used with LaTeX, but not XeTeX. Some time ago I decided to stick with LaTeX. Load the KOMA exporter. #+begin_src emacs-lisp (eval-after-load 'ox '(require 'ox-koma-letter)) #+end_src - Understanding KOMA and how to use it - There are 4 ways to set letter metadata, listed "from the most specific to the most general" (not sure exactly what this statement means, and the conclusion of my notes tries to make sense of what is really going on here and what is the best way to do things) - Org option lines (ORG) - Separate Org latex classes (LTX) - Emacs Lisp variables (LISP) - Letter Class Option files (LCO) - Notes and thoughts on the ways to use it - LTX - By following the setup directions, you do this, creating "my-letter" class - Familiar and easy if you already know LaTeX - At some point in your workflow, you *must* define a class to use, anyway - Very easy to do, just define the class template and set =org-koma-letter-default-class= - ORG - Simple way that makes it very easy to just focus on the document content - This metadata takes highest priority in the workflow - So you should set your typical defaults in LISP or LCO and customize it here. This is exactly what I wanted to know. - This lets you do your tweaking in each unique file while relying on the most common defaults defined elsewhere - LISP - Very familiar style of configuring things - LCO - LCO == Letter Class Option filess - LCO files are TeX - They are included in the generated TeX source code from the letter - Gives *full* access to KOMA-Script - Big deal, because not everything is exposed through ORG or LISP - Also gives full access to any and all TeX and LaTeX code - LCO files are a KOMA-Script thing, so they are a LaTeX thing - #+begin_quote Letter metadata set in LCO files overwrites letter metadata set in Emacs variables but not letter metadata set in the Org file. #+end_quote - When you include multiple LCO files, they are evaluted LIFO. Properties are set as they first appear, and are not set again. Say you include "MyGeneralStuffForAnyLetter.lco" and then include "MyStuffSpecificToThisLetter.lco". The specific stuff will get set first. Then general stuff will get set last. - Surely there is a better way to phrase this. I will work on that. - Recommendations - What is the easiest way to starat using KOMA-Script based on what you know today? - If you don't know any of the approaches - Then choose between learning LaTeX and Org - If you only know LaTeX - Then you will use the LTX/LCO metadata approach - If you only know ORG - Then you will use the ORG metadata approach - If you only know ORG and LISP - Then you will use the LISP approach for general metadata and the ORG approach specific metadata - If you know LTX/LCO, ORG, and LISP - Then you have total flexibility - The fact is that - ORG settings always trump LTX/LCO and LISP - LISP settings are a subset of all of the settings available in KOMA-Script, so you will always have to fall back to LTX/LCO if you want to use unexposed features - LCO files are just plain old LaTeX, which you already know - So the best thing to do - Is to use ORG for letter-specific settings - And LTX for general settings - Everything is a lot simpler this way because - One less metadata approach to keep track of - All KOMA-Script features are present - Need to learn details of KOMA-Script package anyway Configure the default class. [[https://tex.stackexchange.com/questions/102922/how-can-i-get-us-letter-output-from-koma-scripts-scrlttr2-class][This]] post explains how to default the US letter size. That is the likely default for my printed correspondence. #+begin_src emacs-lisp (eval-after-load 'ox-koma-letter '(progn (add-to-list 'org-latex-classes '("my-letter" "\\documentclass[paper=letter, pagesize, fontsize=10pt, parskip]{scrlttr2} \\usepackage[english]{babel} \\usepackage[osf]{mathpazo}")) (setq org-koma-letter-default-class "my-letter"))) #+end_src There are two formats for the letters: [[http://orgmode.org/w/?p%3Dworg.git%3Ba%3Dblob%3Bf%3Dexporters/koma-letter-new-example.org%3Bh%3D180a9a0e10dd8f7483a67946daf36732c316f821%3Bhb%3D180a9a0e10dd8f7483a67946daf36732c316f821][heading-based]] and [[http://orgmode.org/w/?p%3Dworg.git%3Ba%3Dblob%3Bf%3Dexporters/koma-letter-example.org%3Bh%3De21b8b00c3e895be9dd573d02ea84b08796296a3%3Bhb%3De21b8b00c3e895be9dd573d02ea84b08796296a3][property-based]]. Set up my default LCO files. #+begin_src emacs-lisp (setq org-koma-letter-class-option-file "UScommercial9 KomaDefault") #+end_src **** ispell Doing literate programming a *lot*… it is a hassle to spell-check source blocks, so don't. Actually, there are lots of things that I probably don't want to check and this list is growing. All of the entries are explained here. Never ispell org source blocks: #+begin_src emacs-lisp (add-to-list 'ispell-skip-region-alist '("^#\\+begin_src ". "#\\+end_src$")) #+end_src Never ispell org source blocks defined in upper case: #+begin_src emacs-lisp (add-to-list 'ispell-skip-region-alist '("^#\\+BEGIN_SRC ". "#\\+END_SRC$")) #+end_src Never ispell org example blocks: #+begin_src emacs-lisp (add-to-list 'ispell-skip-region-alist '("^#\\+begin_example ". "#\\+end_example$")) (add-to-list 'ispell-skip-region-alist '("^#\\+BEGIN_EXAMPLE ". "#\\+END_EXAMPLE$")) #+end_src Properties block in org do not need to be ispelled #+begin_src emacs-lisp (add-to-list 'ispell-skip-region-alist '("\:PROPERTIES\:$" . "\:END\:$")) #+end_src Footnotes in org should not be ispelled: #+begin_src emacs-lisp (add-to-list 'ispell-skip-region-alist '("\\[fn:.+:" . "\\]")) #+end_src Footnoes in org that have http links that are line breaked should not be ispelled: #+begin_src emacs-lisp (add-to-list 'ispell-skip-region-alist '("^http" . "\\]")) #+end_src Verbatim regions in org mode should not be ispelled: #+begin_src emacs-lisp (add-to-list 'ispell-skip-region-alist '("=.*" . ".*=")) #+end_src In org I often use bold text in lists, and they should never be ispelled because they are usually abbreviations or other non-words: #+begin_src emacs-lisp (add-to-list 'ispell-skip-region-alist '("- \\*.+" . ".*\\*: ")) #+end_src Most of the default org export properties should be ignored because they are not words and I may ispell them manually when desired: #+begin_src emacs-lisp (let (void) (--each '("ATTR_LATEX" "AUTHOR" "CREATOR" "DATE" "DESCRIPTION" "EMAIL" "EXCLUDE_TAGS" "HTML_CONTAINER" "HTML_DOCTYPE" "HTML_HEAD" "HTML_HEAD_EXTRA" "HTML_LINK_HOME" "HTML_LINK_UP" "HTML_MATHJAX" "INFOJS_OPT" "KEYWORDS" "LANGUAGE" "LATEX_CLASS" "LATEX_CLASS_OPTIONS" "LATEX_HEADER" "LATEX_HEADER_EXTRA" "OPTIONS" "SELECT_TAGS" "STARTUP" "TITLE") (gcr/ispell-a2isra (gcr/ispell-org-header-lines-regexp it)))) #+end_src **** Hooks Configure =org= mode hooks to make it easy to do the most commonly performed operations. Bit of a mystery that I couldn't =local-set-key= with one particular binding. Found a way that /does/ work with the help of Jorge and Peak. I'm OK with it remaining a mystery for now. #+begin_src emacs-lisp (define-key org-mode-map (kbd "C-,") (lambda () (interactive) (insert " \\larr "))) #+end_src #+begin_src emacs-lisp (defun gcr/org-mode-hook () (local-set-key (kbd "C-1") 'org-narrow-to-subtree) (local-set-key (kbd "M-1") 'widen) (local-set-key (kbd "C-2") 'gcr/org-edit-src-code-plus-name) (local-set-key (kbd "C-3") 'org-table-edit-field) (local-set-key (kbd "s-h") 'org-babel-check-src-block) (local-set-key (kbd "s-i i") 'org-babel-insert-header-arg) (local-set-key (kbd "s-j") 'org-babel-previous-src-block) (local-set-key (kbd "s-k") 'org-babel-next-src-block) (local-set-key (kbd "s-l") 'org-babel-demarcate-block) (local-set-key (kbd "s-;") 'org-babel-view-src-block-info) (local-set-key (kbd "s-b x") 'org-babel-expand-src-block) (local-set-key (kbd "s-b s") 'org-babel-switch-to-session) (local-set-key (kbd "s-b c") 'org-babel-switch-to-session-with-code) (local-set-key (kbd "s-o") 'org-babel-execute-maybe) (local-set-key (kbd "s-t") 'org-babel-tangle) (local-set-key (kbd "s-x") 'org-babel-do-key-sequence-in-edit-buffer) (local-set-key (kbd "s-w w") 'org-export-dispatch) (local-set-key (kbd "s-") 'org-babel-execute-buffer) (local-set-key (kbd "s-i d") 'org-display-inline-images) (local-set-key (kbd "s-i r") 'org-remove-inline-images) (local-set-key (kbd "C-.") (lambda () (interactive) (insert " \\rarr "))) (local-set-key (kbd "$") 'yf/org-electric-dollar) (when (and (fboundp 'guide-key-mode) guide-key-mode) (guide-key/add-local-guide-key-sequence "C-c") (guide-key/add-local-guide-key-sequence "C-c C-x") (guide-key/add-local-highlight-command-regexp "org-")) (fci-mode) (gcr/untabify-buffer-hook) (turn-on-stripe-table-mode) (linum-mode) (wrap-region-mode t)) (add-hook 'org-mode-hook 'gcr/org-mode-hook) #+end_src Configure the =org= =babel= source code editing buffer with a key to make it easy to exit. This is consistent with the approach of "same to exit as enter". #+begin_src emacs-lisp (defun gcr/org-src-mode-hook () (local-set-key (kbd "C-2") 'org-edit-src-exit) (visual-line-mode)) (add-hook 'org-src-mode-hook 'gcr/org-src-mode-hook) #+end_src ** Keyboard Echo keystrokes immediately: #+begin_src emacs-lisp (setq echo-keystrokes 0.02) #+end_src * Keybindings :PROPERTIES: :noweb-ref: Keybindings :END: Key-Chord [fn:93a799cf: http://melpa.org/#/key-chord] everything. It's documentation gives /the/ tip: keep chords limited to two fingers on the same hand if you can. I'll expand on this to use two hands, intionally, to specify the urgency of the operation about to be performed. The package /just works/ exactly as you would expect, and it is delightful. It is really fast, too. I tried out Key-Combo [fn:6f1e75f8: https://github.com/uk-ar/key-combo] and it seems really great. I just couldn't get it working quickly though, so I didn't try migrating beyond the hour or two that I invested. Think of Key-Chord as letting you add modifier keys *anywhere* and *anyhow* you want (be open minded here). Be pretty careful in chord specification though. My rough approach is: - *CLOSE* (continuity keys) - Use alphanumeric/symbol key-chords when - The combination is obvious… like ".." \rarr "…" - There is *no* chance that it could inadvertently be pressed; recalling that /both/ directions must be considered - Excluding alphanumeric leaves; =` - = [ ] \ ; ' , . /= - Likely offenders: =- = ; ' , .= - Leaving: =` [ ] \ /= - Left hand: 12x5 - Right hand only: 7x5 - 95 possible if this is right - Preferences: [, ], \… - Likelihood of usage? low - Choosing a global mapping that works in all modes will involve a lot of work - Tough to choose these when =META= keys are easily within reach instead - *NEAR* - Goal is to minimize finger travel - Keys used most frequently - In order of preference: - C-#keys :: 10 - C-F keys :: 6 (3 easily in reach on one hand) - *FAR* (discontinuity keys) - Super:any-one :: (12+10+11+26)=59 - *FURTHER* - Use =[S|C|M|S]F:5+= keys :: 8x4=32 bindings #+begin_src emacs-lisp (require 'key-chord) (key-chord-mode 1) (setq key-chord-two-keys-delay 0.1) #+end_src =M-x= truly is the Emacs command line [fn:d0a5f045: https://aaronhawley.livejournal.com/28413.html]. Sometimes you want to temporarily bind keys. Haven't much of a need yet myself, but when the time comes, this [fn:685d5985: https://github.com/abo-abo/centimacro] looks like a great option to have. Generally disallow stomping of global key-mappings unless it makes sense to me (thank you Stefan Monnier for pointing out that referencing the map variable is all it takes): #+begin_src emacs-lisp (defadvice global-set-key (before check-keymapping activate) (let* ((key (ad-get-arg 0)) (new-command (ad-get-arg 1)) (old-command (lookup-key global-map key))) (when (and old-command (not (equal old-command new-command)) (not (equal old-command 'digit-argument)) (not (equal old-command 'negative-argument)) (not (equal old-command 'ns-print-buffer)) (not (equal old-command 'move-beginning-of-line)) (not (equal old-command 'execute-extended-command)) (not (equal new-command 'execute-extended-command)) (not (equal old-command 'ns-prev-frame)) (not (equal old-command 'ns-next-frame)) (not (equal old-command 'mwheel-scroll)) (not (equal new-command 'diff-hl-mode)) (not (equal new-command 'my-eval-expression)) (not (equal old-command 'list-buffers)) (not (equal new-command 'gcr/vc-map)) (not (equal new-command 'projectile-find-file)) ) (warn "Just stomped the global-map binding for %S, replaced %S with %S" key old-command new-command)))) #+end_src These key-bindings are custom for me and I've been using them for so long, and that makes it rig+1ht. There are always opportunities for improvement, though. Recently it dawned on me that it is poor-form to waste 3 function keys on the same task, so I rebound =F1= to different modifiers that I hope are consistent, and free up space, too. My preference is to leave =F5=, =F6, and =F7= generally unbound and available for similar operations that are performed in most programming modes. For example, =F5= will execute code in any Lisp-like environment. Guide: - NON-DISRUPTIVE :: hands on home, no finger strain, C-[(2|3)|(9|0)] - SLIGHTLY-DISRUPTIVE :: hands on home, slight finger strain, C-[1|-] - DISRUPTIVE :: hands on keyboard, not home, palms are home - VERY-DISRUPTIVE :: hands on keyboard, not home, palms are moved from home ** NON-DISRUPTIVE Easily select regions: #+begin_src emacs-lisp (global-set-key (kbd "C-'") 'er/expand-region) #+end_src ace-jumping is frequent, too, and this one is perfect all home keys same, dominant strong hand: #+begin_src emacs-lisp (key-chord-define-global "jk" 'ace-jump-mode) #+end_src Using =ace-jump= will introduce a new idea to you of easily jumping around within a buffer. From you, from wherever you jump /to/, you need jump /back/. Make it really really easy to do so. #+begin_src emacs-lisp (key-chord-define-global "m," 'ace-jump-mode-pop-mark) #+end_src multiple cursor mode… I kept these together because until I make an image, it would be too confusing to keep them in the non and slightly disruptive sections, as they are clearly that: #+begin_src emacs-lisp (global-set-key (kbd "M-9") 'mc/edit-lines) (global-set-key (kbd "M-0") 'mc/mark-next-like-this) (global-set-key (kbd "M--") 'mc/mark-all-like-this) (global-set-key (kbd "M-8") 'mc/mark-previous-like-this) #+end_src ace-window is frequent, is beginning to adhere to a pattern of dual approaches: #+begin_src emacs-lisp (key-chord-define-global "nm" 'ace-window) #+end_src Save 3 bytes: #+begin_src emacs-lisp (key-chord-define-global "3." 'gcr/insert-ellipsis) #+end_src Indent with spaces for the likely scenario: #+begin_src emacs-lisp (key-chord-define-global "4 " (lambda () (interactive) (insert " "))) #+end_src German umlauts for a, o, and u: #+begin_src emacs-lisp (key-chord-define-global (concat "A" "{") (lambda () (interactive) (insert "ä"))) (key-chord-define-global (concat "A" "}") (lambda () (interactive) (insert "Ä"))) (key-chord-define-global (concat "O" "{") (lambda () (interactive) (insert "ö"))) (key-chord-define-global (concat "O" "}") (lambda () (interactive) (insert "Ö"))) (key-chord-define-global (concat "U" "{") (lambda () (interactive) (insert "ü"))) (key-chord-define-global (concat "U" "}") (lambda () (interactive) (insert "Ü"))) #+end_src Arrows, so many: #+begin_src emacs-lisp (global-set-key (kbd "C-,") (lambda () (interactive) (insert "←"))) (global-set-key (kbd "C-.") (lambda () (interactive) (insert "→"))) #+end_src Nice for UML, and French? #+begin_src emacs-lisp (key-chord-define-global "<<" (lambda () (interactive) (insert "«"))) (key-chord-define-global ">>" (lambda () (interactive) (insert "»"))) #+end_src It is great to =ace-jump= to things. How about making deletions of contiguous text as easy and fast?! This library will makes deletes blazingly fast!y #+begin_src emacs-lisp (key-chord-define-global "jl" 'ace-jump-zap-up-to-char) (key-chord-define-global "j;" 'ace-jump-zap-to-char) #+end_src Jumping to lines actually happens a lot. When you look at this layout, remember, or rather consider, that what you jump to, or navigate to, is layered in the sense that the granularity of your actions changes and all actions provided here are helpful for those different situations. This used to be =kc-df= but I typed =df= for data.frame so I had to change it, as well as the following which used to be =cv=. That wasn't good either because it is a painful reach. I need to document the lessons learned above. df-jk make so much more sense, though, and I came back to this to recall why I made this choice. This is an exploration question again because the simplicity and symmettry of df-jk is simpler. I am going to try using shift as a modifier key in the key-chord space. I'll use capital letters. Upon typing that I realized that I don't like this idea, it takes this binding from a non-disruptive to slightly-disruptive. I'll leave this alone again. #+begin_src emacs-lisp (key-chord-define-global "fg" 'goto-line) #+end_src In the same spirit of poppping the mark with =ace-jump=, follow a similar appraoch for =goto-line=. #+begin_src emacs-lisp (key-chord-define-global "vb" 'pop-to-mark-command) #+end_src Do nearly a =IKJL= style up/down/left/right arrow key, using using chords, saves a trip. You might wonder why I would use this when ace-jump-window is available? Good question. Sometimes you know exactly what buffer you want, so jump to it, and sometimes you just don't, and that is when you do it this way: #+begin_src emacs-lisp (key-chord-define-global "JK" (lambda () (interactive) (other-window 1))) (key-chord-define-global "KL" (lambda () (interactive) (next-buffer))) (key-chord-define-global "L:" (lambda () (interactive) (previous-buffer))) #+end_src Web-searches occur quite frequently once you've a nice work-flow established. The keys in that mode are: - w :: word - s :: symbol - l :: line - r :: region #+begin_src emacs-lisp (key-chord-define-global "gt" 'google-this-mode-submap) #+end_src These actions appear in order of importance, and thus frequency of use Do the /right thing/ for getting to the start of the line! #+begin_src emacs-lisp (global-set-key (kbd "C-a") 'beginning-of-line-dwim) #+end_src I use VC quite frequently. This is easy to reach, and does what must be done: #+begin_src emacs-lisp (global-set-key (kbd "C-;") 'vc-next-action) #+end_src Check =git= status: #+begin_src emacs-lisp (global-set-key (kbd "C-M-;") 'magit-status) #+end_src You don't moves lines or regions a ton, but when you do, you usually can't use the arrow keys per mode, so use chords instead. #+begin_src emacs-lisp (key-chord-define-global "yu" 'move-text-up) (key-chord-define-global "hj" 'move-text-down) #+end_src Now that =ispell= is configured nicely, I use it /all/ the time. Make that easy. First tried "is" for "ispell". Loved it. Then remembered that it is a common key combination. Forehead smack! #+begin_src emacs-lisp (key-chord-define-global "qp" 'ispell) (key-chord-define-global "qo" 'ispell-word) #+end_src W for Writegood. #+begin_src emacs-lisp (key-chord-define-global "wm" 'writegood-mode) (key-chord-define-global "wl" 'writegood-grade-level) (key-chord-define-global "wz" 'writegood-reading-ease) #+end_src Use the default Langtool bindings. #+begin_src emacs-lisp (define-prefix-command 'gcr/langtool-map) (key-chord-define-global "qk" 'gcr/langtool-map) (define-key gcr/langtool-map "c" 'langtool-check-buffer) (define-key gcr/langtool-map "C" 'langtool-correct-buffer) (define-key gcr/langtool-map "j" 'langtool-goto-previous-error) (define-key gcr/langtool-map "k" 'langtool-show-message-at-point) (define-key gcr/langtool-map "l" 'langtool-goto-next-error) (define-key gcr/langtool-map "q" 'langtool-check-done) #+end_src Easily browse URLs. Surely there is a more refind way. This is the first step. #+begin_src emacs-lisp (key-chord-define-global "wm" 'writegood-mode) #+end_src Occur has 3 cases. I like to use it to explore the unknown. #+begin_src emacs-lisp (global-set-key (kbd "M-s p") 'gcr/occur-dwim) #+end_src Comment and uncomment anything: #+begin_src emacs-lisp (key-chord-define-global "qi" 'gcr/comment-or-uncomment) #+end_src ** SLIGHTLY-DISRUPTIVE Anything having to do with version control differences: #+begin_src emacs-lisp (define-prefix-command 'gcr/vc-map) (global-set-key (kbd "s-d") 'gcr/vc-map) (define-key gcr/vc-map "h" 'diff-hl-mode) (define-key gcr/vc-map "e" 'vc-ediff) (define-key gcr/vc-map "d" 'vc-diff) (define-key gcr/vc-map "u" 'vc-revert) #+end_src smex integration points: #+begin_src emacs-lisp (global-set-key (kbd "M-x") 'smex) (global-set-key (kbd "M-X") 'smex-major-mode-commands) (global-set-key (kbd "C-c C-c M-x") 'execute-extended-command) #+end_src Try to open a file just in this project: #+begin_src emacs-lisp (global-set-key (kbd "C-x C-p") 'projectile-find-file) #+end_src auto-completeness #+begin_src emacs-lisp (global-set-key (kbd "C-4") 'auto-complete) #+end_src Switching buffers occurs so frequently that this needs to be here, and perhaps I will know I need a better binding later. #+begin_src emacs-lisp (key-chord-define-global "sb" 'ido-switch-buffer) #+end_src ace-window navigation: #+begin_src emacs-lisp (global-set-key (kbd "C--") 'ace-window) #+end_src Make it easy to enter Unicode stuff. Total hack warning, may use the =2= key somewhere else, but, until that happens, this is the perfect place to put it. So, it isn't a hack! #+begin_src emacs-lisp (define-prefix-command 'gcr/two-key-map) (global-set-key (kbd "s-2") 'gcr/two-key-map) #+end_src #+begin_src emacs-lisp (define-prefix-command 'gcr/double-struck-map) (define-key gcr/two-key-map "s" 'gcr/double-struck-map) (define-key gcr/double-struck-map "A" (lambda () (interactive) (insert "𝔸"))) (define-key gcr/double-struck-map "B" (lambda () (interactive) (insert "𝔹"))) (define-key gcr/double-struck-map "C" (lambda () (interactive) (insert "ℂ"))) (define-key gcr/double-struck-map "D" (lambda () (interactive) (insert "𝔻"))) (define-key gcr/double-struck-map "E" (lambda () (interactive) (insert "𝔼"))) (define-key gcr/double-struck-map "F" (lambda () (interactive) (insert "𝔽"))) (define-key gcr/double-struck-map "G" (lambda () (interactive) (insert "𝔾"))) (define-key gcr/double-struck-map "H" (lambda () (interactive) (insert "ℍ"))) (define-key gcr/double-struck-map "I" (lambda () (interactive) (insert "𝕀"))) (define-key gcr/double-struck-map "J" (lambda () (interactive) (insert "𝕁"))) (define-key gcr/double-struck-map "K" (lambda () (interactive) (insert "𝕂"))) (define-key gcr/double-struck-map "L" (lambda () (interactive) (insert "𝕃"))) (define-key gcr/double-struck-map "M" (lambda () (interactive) (insert "𝕄"))) (define-key gcr/double-struck-map "N" (lambda () (interactive) (insert "ℕ"))) (define-key gcr/double-struck-map "O" (lambda () (interactive) (insert "𝕆"))) (define-key gcr/double-struck-map "P" (lambda () (interactive) (insert "ℙ"))) (define-key gcr/double-struck-map "Q" (lambda () (interactive) (insert "ℚ"))) (define-key gcr/double-struck-map "R" (lambda () (interactive) (insert "ℝ"))) (define-key gcr/double-struck-map "S" (lambda () (interactive) (insert "𝕊"))) (define-key gcr/double-struck-map "T" (lambda () (interactive) (insert "𝕋"))) (define-key gcr/double-struck-map "U" (lambda () (interactive) (insert "𝕌"))) (define-key gcr/double-struck-map "V" (lambda () (interactive) (insert "𝕍"))) (define-key gcr/double-struck-map "W" (lambda () (interactive) (insert "𝕎"))) (define-key gcr/double-struck-map "X" (lambda () (interactive) (insert "𝕏"))) (define-key gcr/double-struck-map "Y" (lambda () (interactive) (insert "𝕐"))) (define-key gcr/double-struck-map "Z" (lambda () (interactive) (insert "ℤ"))) (define-key gcr/double-struck-map "a" (lambda () (interactive) (insert "𝕒"))) (define-key gcr/double-struck-map "b" (lambda () (interactive) (insert "𝕓"))) (define-key gcr/double-struck-map "c" (lambda () (interactive) (insert "𝕔"))) (define-key gcr/double-struck-map "d" (lambda () (interactive) (insert "𝕕"))) (define-key gcr/double-struck-map "e" (lambda () (interactive) (insert "𝕖"))) (define-key gcr/double-struck-map "f" (lambda () (interactive) (insert "𝕗"))) (define-key gcr/double-struck-map "g" (lambda () (interactive) (insert "𝕘"))) (define-key gcr/double-struck-map "h" (lambda () (interactive) (insert "𝕙"))) (define-key gcr/double-struck-map "i" (lambda () (interactive) (insert "𝕚"))) (define-key gcr/double-struck-map "j" (lambda () (interactive) (insert "𝕛"))) (define-key gcr/double-struck-map "k" (lambda () (interactive) (insert "𝕜"))) (define-key gcr/double-struck-map "l" (lambda () (interactive) (insert "𝕝"))) (define-key gcr/double-struck-map "m" (lambda () (interactive) (insert "𝕞"))) (define-key gcr/double-struck-map "n" (lambda () (interactive) (insert "𝕟"))) (define-key gcr/double-struck-map "o" (lambda () (interactive) (insert "𝕠"))) (define-key gcr/double-struck-map "p" (lambda () (interactive) (insert "𝕡"))) (define-key gcr/double-struck-map "q" (lambda () (interactive) (insert "𝕢"))) (define-key gcr/double-struck-map "r" (lambda () (interactive) (insert "𝕣"))) (define-key gcr/double-struck-map "s" (lambda () (interactive) (insert "𝕤"))) (define-key gcr/double-struck-map "t" (lambda () (interactive) (insert "𝕥"))) (define-key gcr/double-struck-map "u" (lambda () (interactive) (insert "𝕦"))) (define-key gcr/double-struck-map "v" (lambda () (interactive) (insert "𝕧"))) (define-key gcr/double-struck-map "w" (lambda () (interactive) (insert "𝕨"))) (define-key gcr/double-struck-map "x" (lambda () (interactive) (insert "𝕩"))) (define-key gcr/double-struck-map "y" (lambda () (interactive) (insert "𝕪"))) (define-key gcr/double-struck-map "z" (lambda () (interactive) (insert "𝕫"))) (define-key gcr/double-struck-map "0" (lambda () (interactive) (insert "𝟘"))) (define-key gcr/double-struck-map "1" (lambda () (interactive) (insert "𝟙"))) (define-key gcr/double-struck-map "2" (lambda () (interactive) (insert "𝟚"))) (define-key gcr/double-struck-map "3" (lambda () (interactive) (insert "𝟛"))) (define-key gcr/double-struck-map "4" (lambda () (interactive) (insert "𝟜"))) (define-key gcr/double-struck-map "5" (lambda () (interactive) (insert "𝟝"))) (define-key gcr/double-struck-map "6" (lambda () (interactive) (insert "𝟞"))) (define-key gcr/double-struck-map "7" (lambda () (interactive) (insert "𝟟"))) (define-key gcr/double-struck-map "8" (lambda () (interactive) (insert "𝟠"))) (define-key gcr/double-struck-map "9" (lambda () (interactive) (insert "𝟡"))) #+end_src Pop up help: #+begin_src emacs-lisp (global-set-key (kbd "s-p") 'gcr/describe-thing-in-popup) #+end_src Code-folding: #+begin_src emacs-lisp (global-set-key (kbd "M-3") 'hs-toggle-hiding) #+end_src Do smart new line inside, indenting given the mode: #+begin_src emacs-lisp (global-set-key (kbd "s-") 'gcr/smart-open-line) #+end_src A lot of times you have the need to just go to the next line, and indent it, and start typing. For years I just went to the end of the current like, hit return, and well there you are. Mentally I should have profiled it by now that it should be a simple action, so now it is. #+begin_src emacs-lisp (global-set-key (kbd "M-") 'gcr/lazy-new-open-line) #+end_src Use a nicer =eval-expression= approach. #+begin_src emacs-lisp (global-set-key (kbd "M-:") 'my-eval-expression) #+end_src List buffers in a more rich way. #+begin_src emacs-lisp (global-set-key (kbd "C-x C-b") 'ibuffer) #+end_src Toggle utility buffers #+begin_src emacs-lisp (key-chord-define-global "f9" 'gcr/util-cycle) #+end_src ** VERY DISRUPTIVE F10 should be left alone. Start NeoTree: #+begin_src emacs-lisp (global-set-key (kbd "") 'neotree-toggle) #+end_src These do get used a lot believe it or not: #+begin_src emacs-lisp (global-set-key (kbd "M-7") 'gcr/insert-timestamp) (global-set-key (kbd "s-7") 'gcr/insert-timestamp*) (global-set-key (kbd "C-7") 'gcr/insert-datestamp) #+end_src I used to use =F5= to run code. Probably because of various editors that I had used before. I do want that familiarity, because I use those functions a lot for a certain style of developing. I will use =C-F5=. Manage every font size: #+begin_src emacs-lisp (gcr/on-gui (global-set-key (kbd "s-") 'gcr/text-scale-increase) (global-set-key (kbd "M-") 'gcr/text-scale-decrease)) #+end_src Thank [[http://oremacs.com/2015/03/15/search-with-apropos/][Oleh]] getting us up to speed on all of the =apropos= areas. Thank you [[https://disqus.com/by/disqus_COwPSAc69c/][Phil]] for the map. Thank you [[http://irreal.org/blog/?p%3D3792][Jon]] for reminding us. I have only ever used =apropos=. It was not very often. Great to know of the available granularity. #+begin_src emacs-lisp (global-set-key (kbd "M-") 'apropos-map) (define-prefix-command 'apropos-map nil "Apropos (a(propos),d(documentation),c(ommand),i(nfo),l(ibrary),v(ariable))") (define-key apropos-map (kbd "a") 'apropos) (define-key apropos-map (kbd "d") 'apropos-documentation) (define-key apropos-map (kbd "c") 'apropos-command) (define-key apropos-map (kbd "i") 'info-apropos) (define-key apropos-map (kbd "l") 'apropos-library) (define-key apropos-map (kbd "v") 'apropos-variable) #+end_src Helper stuff: #+begin_src emacs-lisp (global-set-key (kbd "C-") 'emacs-index-search) (global-set-key (kbd "S-") 'elisp-index-search) (global-set-key (kbd "C-") 'imenu-anywhere) #+end_src Re-size the current windows [fn:7293bf39: http://www.emacswiki.org/emacs/WindowResize]: #+begin_src emacs-lisp (global-set-key (kbd "s-") 'shrink-window) (global-set-key (kbd "s-") 'enlarge-window) (global-set-key (kbd "s-") 'enlarge-window-horizontally) (global-set-key (kbd "s-") 'shrink-window-horizontally) #+end_src *Always* leave =F5= open. It is discussed above. Update the world clocks: #+begin_src emacs-lisp (global-set-key (kbd "") 'list-world-time) #+end_src Always leave =F11= open. * Modes :PROPERTIES: :noweb-ref: Modes :END: v1: The stuff that I commonly use may -eventually want to end up in =prog-mode=, but I'm still not sure what really -uses that and how I may being re-factoring. v2: The programming modes have some redundancy. Sometimes I feel like it ought to be refactored. Other times I feel like it is not worth the effort because the flavor you want for seemingly similar mode configurations may be very different once you think about it for a little while. ** C Language Integrated Production System (CLIPS) [fn:d383cc00: http://clipsrules.sourceforge.net/] CLIPS is a very special thing. OSS, expertly developed and used. Truly a hidden gem among the muck. =clips-mode= [fn:36f704bf: https://github.com/grettke/clips-mode] has had a long life behind it, and only some time ago the folks at MELPA helped me to get it in there as the original maintainers were not to be found nor did the folks at that university reply to emails about licensing and lineage. #+begin_src emacs-lisp (require 'clips-mode) #+end_src ** Comint =comint-mode= is only maybe the second most important thing for making Emacs really, really special. #+begin_src emacs-lisp (setq comint-scroll-to-bottom-on-input 'this) (setq comint-scroll-to-bottom-on-output 'others) (setq comint-move-point-for-output 'others) (setq comint-show-maximum-output t) (setq comint-scroll-show-maximum-output t) (setq comint-move-point-for-output t) #+end_src This configuration had been working fine for a long time. The intent was for it to be crystal clear that the prompt line in comint buffers would be read only. This turned out to be a mistake; though I am not sure why, when, or how it became a mistake. Nonetheless, this should be left alone. The way the issue here manifested was that all ℝ buffers opened by =ess= were 100% read only which obviously is a *big issue* if you actually want to use! ROFL #+begin_src emacs-lisp (setq comint-prompt-read-only nil) #+end_src ** CSS #+begin_src emacs-lisp (defun gcr/css-modehook () (fci-mode) (visual-line-mode) (gcr/untabify-buffer-hook) (local-set-key (kbd "RET") 'newline-and-indent)) (add-hook 'css-mode-hook 'gcr/css-modehook) #+end_src ** Emacs Lisp Make it obvious whether or not it is lexically scoped [fn:c4baca78: http://marmalade-repo.org/packages/lexbind-mode] or not and don't show that message whenever you enter a scratch buffer [fn:dfc44625: https://www.gnu.org/software/emacs/manual/html_node/elisp/Startup-Summary.html]. You may read more about Lisp Doc here [fn:d9e2a4de: https://www.gnu.org/software/emacs/manual/html_node/emacs/Lisp-Doc.html]. You may read more about default console messages here [fn:e67fd3ff: https://www.gnu.org/software/emacs/manual/html_node/elisp/Startup-Summary.html]. =eval-expression= gets really, really handy once you get into the Emacs lifecycle. My goal was to enable =smartparens= in the minibuffer, and it didn't work. I posted a question on it, and Drew Adams drew.adams@oracle.com explained how =icicle= provides a better version of =eval-expression=, and how in lieu of that, =pp-eval-expression= is even better. Michael Heerdegen shared his solution [fn:321475a6: https://lists.gnu.org/archive/html/help-gnu-emacs/2014-07/msg00135.html] for a rich modeline evaluator. #+begin_src emacs-lisp (defun gcr/elisp-eval-buffer () "Intelligently evaluate an Elisp buffer." (interactive) (gcr/save-all-file-buffers) (eval-buffer)) (defun gcr/elisp-mode-local-bindings () "Helpful behavior for Elisp buffers." (local-set-key (kbd "s-l eb") 'gcr/elisp-eval-buffer) (local-set-key (kbd "s-l ep") 'eval-print-last-sexp) (local-set-key (kbd "s-l td") 'toggle-debug-on-error) (local-set-key (kbd "s-l mef") 'macroexpand) (local-set-key (kbd "s-l mea") 'macroexpand-all) (local-set-key (kbd "s-p") 'gcr/describe-thing-in-popup) (local-set-key (kbd "M-:") 'my-eval-expression) (local-set-key (kbd "#") 'endless/sharp)) (require 'lexbind-mode) (defun gcr/emacs-lisp-mode-hook () (gcr/elisp-mode-local-bindings) (lexbind-mode) (turn-on-eldoc-mode) (gcr/diminish 'eldoc-mode) (aggressive-indent-mode)) (add-hook 'emacs-lisp-mode-hook 'gcr/emacs-lisp-mode-hook) (setq initial-scratch-message nil) #+end_src ** Eshell [fn:063471c9: https://www.gnu.org/software/emacs/manual/html_mono/eshell.html] [fn:46b52b8f: http://www.masteringemacs.org/articles/2010/12/13/complete-guide-mastering-eshell/] [fn:ed7a113f: http://www.khngai.com/emacs/eshell.php] If you've never learned bash or Korn or c-shell, then you are missing out on having some good fun… I mean work, getting work done. That said, I'm a baby when it comes to really using them. It seemed like a good idea to learn some of them well, and one that works seamlessly with Emacs seems like a great idea. Since it is just another Elisp program, it has access to the same scope as everything else running inside Emacs. The resources on this tool are a bit varied and all valuable so I included all of them. The big takeaway is that you've got a "normal" looking shell interface whose commands work transparently with Elisp commands… and that can bey very pleasant. Command completion is available. Commands input in eshell are delegated in order to an alias, a built in command, an Elisp function with the same name, and finally to a system call. Semicolons separate commands. =which= tells you what implementation will satisfy the call that you are going to make. The flag =eshell-prefer-lisp-functions= does what it says. =$$= is the result of the last command. Aliases live in =eshell-aliases-file=. History is maintained and expandable. =eshell-source-file= will run scripts. Since Eshell is not a terminal emulator, you need to tell it about any commands that need to run using a terminal emulator, like anything using curses by adding it to to =eshell-visual-commands=. #+begin_src emacs-lisp (setq eshell-prefer-lisp-functions nil eshell-cmpl-cycle-completions nil eshell-save-history-on-exit t eshell-cmpl-dir-ignore "\\`\\(\\.\\.?\\|CVS\\|\\.svn\\|\\.git\\)/\\'") (eval-after-load 'esh-opt '(progn (require 'em-cmpl) (require 'em-prompt) (require 'em-term) (setenv "PAGER" "cat") (add-hook 'eshell-mode-hook (lambda () (message "Protovision… I have you now.") (setq pcomplete-cycle-completions nil))) (add-to-list 'eshell-visual-commands "ssh") (add-to-list 'eshell-visual-commands "tail") (add-to-list 'eshell-command-completions-alist '("tar" "\\(\\.tar|\\.tgz\\|\\.tar\\.gz\\)\\'")))) #+end_src The =eshell= configuration is a version controlled directory #+begin_src emacs-lisp (defconst gcr/eshell-dir "~/.emacs.d/eshell") (defun gcr/warn-eshell-dir () "Warn of eshell misconfiguration." (interactive) (unless (and (f-symlink? gcr/eshell-dir) (f-directory? gcr/eshell-dir)) (warn "Could not find the eshell directory at: %S. Eshell will continue to function albeit without your customizations." gcr/eshell-dir))) (gcr/warn-eshell-dir) #+end_src #+begin_src emacs-lisp (setq eshell-prompt-regexp "^.+@.+:.+> ") (setq eshell-prompt-function (lambda () (concat (user-login-name) "@" (system-name) ":" (eshell/pwd) "> "))) #+end_src ** Files Try to visit a non-existence file and get prompted to create its parent directories. #+begin_src emacs-lisp (add-to-list 'find-file-not-found-functions #'gcr/create-non-existent-directory) #+end_src ** Graphviz [fn:d05878c1: http://www.graphviz.org/] [fn:4c7193c2: http://marmalade-repo.org/packages/graphviz-dot-mode] [fn:04ffff20: http://orgmode.org/worg/org-contrib/babel/languages/ob-doc-dot.html] #+begin_src emacs-lisp (defun gcr/graphviz-dot-mode-hook () "Personal mode bindings for Graphviz mode." (fci-mode) (visual-line-mode)) (add-hook 'graphviz-dot-mode-hook 'gcr/graphviz-dot-mode-hook) #+end_src An example: #+begin_src dot :file ./images/graphviz.png :noweb-ref no-tangle digraph graphviz { rankdir=LR; label="On Action."; begin [label="Identify the topic.", shape=doublecircle]; dailyuse [label="Act upon it.", shape=doublecircle; style=filled]; begin -> dailyuse [label="Consideration"]; } #+end_src #+NAME: [[file:./images/graphviz.png]] ** Grammar Never though that S&W [fn:be320540: http://www.amazon.com/gp/product/0205632645?ie=UTF8&tag=ucmbread-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=0205632645] would find a home here. It shall because of Matt Might [fn:d7db4b2f: http://matt.might.net/articles/shell-scripts-for-passive-voice-weasel-words-duplicates/], thank you very much, and Writegood-Mode [fn:0afa6fb0: http://bnbeckwith.com/code/writegood-mode.html]. The [[https://github.com/bnbeckwith/writegood-mode][GitHub]] page has more useful notes. Sacha added to it [fn:9dd85741: https://github.com/sachac/artbollocks-mode]. #+begin_src emacs-lisp (require 'writegood-mode) #+end_src LanguageTool [fn:94814ced: https://www.languagetool.org/] and Langtool [fn:e27e3c52: https://github.com/mhayashi1120/Emacs-langtool] work well togethern. #+begin_src emacs-lisp (require 'langtool) (setq langtool-language-tool-jar (concat (getenv "EELIB") "/LanguageTool-2.8/languagetool-commandline.jar")) (setq langtool-mother-tongue "en") (setq langtool-java-bin (concat (getenv "JAVA_HOME") "/bin/java")) #+end_src ** Help My usage pattern for help is to display it, learn what I wish, and move on by closing the buffer. Make this work-flow easier [fn:2c2d78bc: https://emacs.stackexchange.com/questions/7471/change-focus-to-help-buffer-after-running-describe-mode]. #+begin_src emacs-lisp (setq help-window-select t) #+end_src ** ibuffer #+begin_src emacs-lisp (defun gcr/ibuffer-hook () "Personal customizations" (interactive) (ibuffer-vc-set-filter-groups-by-vc-root) (unless (eq ibuffer-sorting-mode 'alphabetic) (ibuffer-do-sort-by-alphabetic))) (add-hook 'ibuffer-hook 'gcr/ibuffer-hook) (setq ibuffer-formats '((mark modified read-only vc-status-mini " " (name 18 18 :left :elide) " " (size 9 -1 :right) " " (mode 16 16 :left :elide) " " (vc-status 16 16 :left) " " filename-and-process))) #+end_src ** IELM [fn:2ef924b6: https://www.gnu.org/software/emacs/manual/html_node/emacs/Lisp-Interaction.html] [fn:8a08ea9e: http://www.emacswiki.org/emacs/InferiorEmacsLispMode] [fn:5c199b8d: http://emacs-fu.blogspot.com/2011/03/ielm-repl-for-emacs.html] =my-eval-expression= makes that task pretty pleasant. The =*scratch*= buffer is also really nice, too. =eval-last-sexp= obviously is a great option, too. Sometimes, though, you want a REPL. Typically it is because you want to play with stuff or have a record of the results that doesn't involve using =eval-print-last-sexp=. Because I have the utility buffer set up in here, it makes it quite unobtrusive and pleasant to use =ielm=. My setup here tries to re-use as much as possible for the standard =lispy= mode setup. That means I use my return handler, so when you want to evalute code in here use =ielm-send-input= instead. This [fn:aee1d8fd: http://www.masteringemacs.org/articles/2010/11/29/evaluating-elisp-emacs/] is a *must-read* article. Joseph G. Gay explained that what makes IELM so powerful is that you may execute commands /within/ the scope of a different buffer. Using =ielm-change-working-buffer= changes the current working buffer to something else. That character is "MATHEMATICAL DOUBLE-STRUCK CAPITAL E". #+begin_src emacs-lisp (defun gcr/ielm-mode-hook () "Personal customizations." (interactive) (gcr/ielm-auto-complete)) (setq ielm-noisy nil) (setq ielm-prompt "𝔼LISP> ") (add-hook 'ielm-mode-hook 'gcr/ielm-mode-hook) #+end_src ** Imenu [fn:58de53db: https://www.gnu.org/software/emacs/manual/html_node/emacs/Imenu.html] [fn:6024eee8: http://www.emacswiki.org/emacs/ImenuMode] For a while I didn't use the menu bar. Then I started using Imenu via IDO. Make it real easy to utilize the things that imenu provides, but make it keyboard driven and available anywhere [fn:dff17af6: http://melpa.milkbox.net/#/imenu-anywhere]. This is a little bit different than =idomenu= [fn:78d70829: http://melpa.milkbox.net/#/idomenu] which is also very nice. The difference between them is that the latter collects tags across all open buffers of the type as the current buffer which is very nice. #+begin_src emacs-lisp (require 'imenu-anywhere) #+end_src That was really nice. It got me curious again about how it might fit since I am using the menu bar again and it seems like a nice thing when working with other people. Configure Imenu to my preference: #+begin_src emacs-lisp (setq imenu-sort-function 'imenu--sort-by-name) #+end_src It was pretty clear even before trying it out that =imenu+= was a good idea [fn:b6404e93: http://www.emacswiki.org/emacs/imenu%2b.el]. #+begin_src emacs-lisp (require 'imenu+) #+end_src I had originally set up Imenu my making request to add its menu in every mode hook so I had it appearing in a bunch of places. That worked fine until the first time I tried tangling a file… which didn't work. The error message was kind of revealing =The mode `' does not support Imenu= which was interesting because I had recently added =imenu= before which tangling worked fine. Testing it out with my simple org init file by removing the Imenu calls revealed the problem. What cause the problem, I'm still not sure, but the solution is only to use Imenu to modes that support it via =font-lock-mode=. #+begin_src emacs-lisp (defun gcr/try-to-add-imenu () "Add Imenu to modes that have `font-lock-mode' activated. Attribution: SRC http://www.emacswiki.org/emacs/ImenuMode" (condition-case nil (imenu-add-to-menubar "Imenu") (error nil))) (add-hook 'font-lock-mode-hook 'gcr/try-to-add-imenu) #+end_src ** Info [fn:c9bf4a1e: http://www.emacswiki.org/emacs/InfoMode] Once you accept Emacs and learn to enjoy Info files you may want to be able to navigate them quickly, even if you haven't read the user manual as I have not. ace-link [fn:4023603c: https://github.com/abo-abo/ace-link] is really a nice way to do that. #+begin_src emacs-lisp (ace-link-setup-default) #+end_src A numeric prefix argument will open up unique Info buffers [fn:0c0a1803: http://mbork.pl/2014-12-27_Info_dispatch]. Of course it will. Of course it will! That explains how to make it easy to use multiple Info buffers per topic. This article makes it easier too using Hydra [fn:68eae9c6: http://oremacs.com/2015/03/17/more-info/]. ** Javascript [fn:152bafed: https://en.wikipedia.org/wiki/ECMAScript] [fn:42427fc4: http://www.emacswiki.org/emacs/JavaScriptMode] =auto-complete= often needs a symlink from =javascript-mode= to =js-mode= added. That link is not version controlled, nor is it created via the API as it makes the check simpler. #+begin_src emacs-lisp (defun gcr/js-mode-hook () (local-set-key (kbd "RET") 'newline-and-indent) (setq js-indent-level 2) (fci-mode) (visual-line-mode) (gcr/untabify-buffer-hook) (linum-mode)) (add-hook 'js-mode-hook 'gcr/js-mode-hook) #+end_src ** LilyPond [fn:6d06e6b9: http://lilypond.org/] All of my experience with musical notation is through GuitarPro [fn:3945829a: http://www.guitar-pro.com/en/index.php?pg=accueil-2&utm_expid=13369301-5.jyDTwdKfQ_CCdEqtpCIynQ.1&utm_referrer=https%3A%2F%2Fwww.google.com%2F] and even there I'm a baby user. Despite that, I've been curious about music theory for a long time and this seems like a good way to take a dip. At first, it didn't seem to work. then I "rebooted" and it seemed to work, but not in org HTML export. This will require further research. ** Lispy A lot of people have downloaded =rainbow-delimiters=, 25377 as of <2014-07-26 Sat>. The documentation is nice. =solarized= has support for it. The documentation says something very specific: #+begin_quote The default colors are intentionally subtle; they are unobtrusive enough to make the mode worth looking at even if you usually don’t like rainbow parentheses modes. #+end_quote Well, that is me, so I am going to install it too. #+begin_src emacs-lisp (require 'rainbow-delimiters) #+end_src #+begin_src emacs-lisp (defconst lispy-modes '(clips-mode-hook emacs-lisp-mode-hook geiser-repl-mode-hook ielm-mode-hook lisp-interaction-mode-hook scheme-mode-hook)) (dolist (h lispy-modes) (add-hook h 'turn-on-smartparens-strict-mode) (add-hook h 'gcr/newline) (add-hook h 'gcr/disable-tabs)) (dolist (h lispy-modes) (when (not (member h '(ielm-mode-hook))) (add-hook h 'turn-on-pretty-mode) (add-hook h 'gcr/untabify-buffer-hook) (add-hook h 'fci-mode) (add-hook h (function (lambda () (hs-minor-mode 1)))) (add-hook h 'linum-mode) (add-hook h 'visual-line-mode) (add-hook h (function (lambda () (add-hook 'local-write-file-hooks 'check-parens)))))) #+end_src ** Make [fn:da03efe9: https://www.gnu.org/software/make/manual/make.html] [fn:202: http://orgmode.org/worg/org-contrib/babel/languages/ob-doc-makefile.html] [fn:203: http://www.emacswiki.org/emacs/MakefileMode] #+begin_src emacs-lisp (defun gcr/make-modehook () (fci-mode) (whitespace-turn-on) (visual-line-mode) (local-set-key (kbd "RET") 'newline-and-indent)) (add-hook 'makefile-mode-hook 'gcr/make-modehook) #+end_src ** Markdown [fn:e43df485: http://jblevins.org/projects/markdown-mode/] I used to think that since org-mode exports to just about everything, that my Markdown usage will be mostly limited to working with files on Github so I turned on Github Flavored Markdown [fn:0b358cc2: https://help.github.com/articles/github-flavored-markdown] mode for README.md files that are likely to appear on Github. That is fine and it doesn't interfere with normal Markdown and also I'm getting more interested in Pandoc so it is nice to have normal Markdown available easily here. GFM seems is in the release now. #+begin_src emacs-lisp (autoload 'markdown-mode "markdown-mode" "Major mode for editing Markdown files" +1) (add-to-list 'auto-mode-alist '("\.markdown'" . gfm-mode)) (add-to-list 'auto-mode-alist '("\.md'" . gfm-mode)) (defun gcr/markdown-mode-hook () "Markdown mode customizations." (interactive) (fci-mode) (visual-line-mode) (local-set-key (kbd "RET") 'newline-and-indent)) (add-hook 'markdown-mode-hook 'gcr/markdown-mode-hook) #+end_src ** Occur Make it really easy to read search results! #+begin_src emacs-lisp (defun gcr/occur-mode-hook () "Personal customizations." (interactive) (turn-on-stripe-buffer-mode) (stripe-listify-buffer)) (add-hook 'occur-mode-hook 'gcr/occur-mode-hook) #+end_src ** Pandoc [fn:d8e34067: http://johnmacfarlane.net/pandoc/] Heard good things about =pandoc-mode= [fn:0cacccd8: https://github.com/joostkremers/pandoc-mode] and I am really looking forward to finding where dharma leads me with this. The mode documentation is here [fn:592907bc: https://joostkremers.github.io/pandoc-mode/]. Good 'old autoloads mean nothing to see here. ** Polymode [fn:918c4a07: https://github.com/vitoshka/polymode] #+begin_quote Object oriented framework for multiple emacs modes based on indirect buffers #+end_quote The status quo for LP with ℝ is =knitr= and my goal is to get first-class support here. Started by reading the home page, I started initial setup and a TODO. The literature on the page is seemingly directed more at someone developing new modes. That seems pretty useful from any perspetive, and I am going to include important points following. #+begin_quote it is worth emphasizing the distinctions between chunks and chunkmodes. Chunks are fragments of text and there might be multiple chunks of the same type in the buffer. In contrast, there is only one chunkmode of some specific type and multiple chunks of this type "share" this chunkmode #+end_quote and also #+begin_quote things like =poly-XXX-mode-map= and =poly-XXX-mode-hook= work just as expected #+end_quote Perhaps a path do understanding the nature of the mode is in "Defining New Polymodes" #+begin_quote In order to define a new polymode =poly-cool-mode= you first have to define or clone a chunkmode object to represent the hostmode, and one or more chunkmodes to represent innermodes. Then define the polymode object =pm-poly/cool= pointing to previously defined host and inner chunkmodes. #+end_quote The example given is of a latex and noweb system: - Define a host mode of a =pm-bchunkmode= for =latex= which is capable of containing embedded languages - Define a =pm-hbtchunkmode= for =noweb= inner language - Defines regexen for identifying a block of this type ala noweb syntax - Define a =pm-polymode-one= using bo them Another example is given showing how you can re-use a host mode. Say you wanted a mode for noweb that could contain chunks of ℝ instead of latex. You can clone the noweb inner-mode definition and then define a new plymode. The vagueness here is intentional because I didn't try it myself. Although I didn't dig deep at all into the details, it is clearly a rich and powerful library. At the very least, it is nice documentation to be read. The next ste is to set it up. The functionality that I'm primarily interested in seems to be here [fn:aee1cbde: https://github.com/vitoshka/polymode/blob/master/modes/poly-R.el]. Skimming it a few things jump out: - There is a base language definition - Therer are *many* host modes for seemingly every markup out there - Noweb, Markdown, Rapport, Yaml, HTML, Knitr, Brew, RC++, C++R, R-Help, Rd, R shell, ESS combinations It is not obvious to me how to set it up. This [fn:3dc322e2: http://blog.revolutionanalytics.com/2014/03/emacs-ess-and-r-for-zombies.html] seems to indicate that one should do as I have done, read the home page, and then go online for tips. Now, I have. This [fn:d1979851: http://johnstantongeddes.org/open%20science/2014/03/26/Rmd-polymode.html] post was very helpful. A little unsure where to go from here, this https://stat.ethz.ch/pipermail/ess-help/2014-May/009926.html post indicates that there are, just as the code said, 4 weaves that may be important: - knitR - knitR-ESS - Sweave - Sweave-ESS Opened up a .Rmd document. Called =polymode-weave= and chose =knitR-ESS=. It generated the corrent =.md= file. Opened up a ℝ help buffer and the Examples section was formatted correctly. Later I saw that I should have also read: - [fn:ea37e53b: http://comments.gmane.org/gmane.emacs.ess.general/6994] - Release post - Good discussion, provides both context and ideas - [fn:3133d97b: http://thread.gmane.org/gmane.emacs.ess.general/8155] - Read this back then and it only makes sense now after reading the documentation - Very thoughtful and flexible and good - Other potentially interesting discussions Load and specify file auto modes: #+begin_src emacs-lisp (require 'poly-R) (require 'poly-markdown) (add-to-list 'auto-mode-alist '("\\.Rmd" . poly-markdown+r-mode)) #+end_src Specify some keymaps that are nearly what I have for =org= for the same tasks: #+begin_src emacs-lisp (define-key polymode-mode-map (kbd "s-e E") 'polymode-set-exporter) (define-key polymode-mode-map (kbd "s-e e") 'polymode-weave) (define-key polymode-mode-map (kbd "s-w s") 'polymode-set-weaver) (define-key polymode-mode-map (kbd "s-w w") 'polymode-weave) (define-key polymode-mode-map (kbd "s-w p") 'polymode-show-process-buffer) (define-key polymode-mode-map (kbd "s-j") 'polymode-previous-chunk) (define-key polymode-mode-map (kbd "s-k") 'polymode-next-chunk) (define-key polymode-mode-map (kbd "s-o k") 'polymode-kill-chunk) (define-key polymode-mode-map (kbd "s-o i") 'polymode-insert-new-chunk) (define-key polymode-mode-map (kbd "s-o m") 'polymode-mark-or-extend-chunk) (define-key polymode-mode-map (kbd "s-o t") 'polymode-toggle-chunk-narrowing) #+end_src ** Ruby [fn:e9aab149: https://www.ruby-lang.org/en/] My first setup of Ruby is primarily for Vagrant, so I didn't dig super deep into the options. The defaults will be just fine. Chef now, too. #+begin_src emacs-lisp (defun gcr/ruby-mode-hook () (interactive) (fci-mode) (gcr/untabify-buffer-hook) (visual-line-mode) (fci-mode) (turn-on-smartparens-strict-mode) (local-set-key (kbd "RET") 'newline-and-indent) (hs-minor-mode 1) (linum-mode)) (add-hook 'ruby-mode-hook 'gcr/ruby-mode-hook) #+end_src ** Scheme [fn:5c0b0c3e: http://library.readscheme.org/index.html] You should probably only use Geiser, forever. [fn:d27bd96d: http://www.nongnu.org/geiser/] Some day I would like to explore =ac-geiser= [fn:6d6fbd53: https://github.com/xiaohanyu/ac-geiser]. #+begin_src emacs-lisp (require 'geiser) (setq geiser-active-implementations '(racket)) (defun gcr/scheme-eval-buffer () "Save and then evaluate the current Scheme buffer with Geiser." (interactive) (gcr/save-all-file-buffers) (geiser-mode-switch-to-repl-and-enter)) (defun gcr/scheme-mode-local-bindings () "Helpful behavior for Scheme buffers." (local-set-key (kbd "") 'gcr/scheme-eval-buffer)) (add-hook 'scheme-mode-hook 'gcr/scheme-mode-local-bindings) (add-to-list 'auto-mode-alist '("\\.scm\\'" . scheme-mode)) (add-to-list 'auto-mode-alist '("\\.rkt\\'" . scheme-mode)) (add-to-list 'auto-mode-alist '("\\.ss\\'" . scheme-mode)) (add-to-list 'auto-mode-alist '("\\.sls\\'" . scheme-mode)) (add-to-list 'auto-mode-alist '("\\.sps\\'" . scheme-mode)) #+end_src ** Sh(hell) "Major mode for editing shell scripts." #+begin_src emacs-lisp (defun gcr/sh-mode-hook () "Personal customizations." (interactive) (turn-on-smartparens-strict-mode) (turn-on-pretty-mode) (gcr/untabify-buffer-hook) (gcr/disable-tabs) (fci-mode) (whitespace-turn-on) (visual-line-mode) (hs-minor-mode 1) (local-set-key (kbd "RET") 'newline-and-indent)) (add-hook 'sh-mode-hook 'gcr/sh-mode-hook) #+end_src ** Shell "Major mode for interacting with an inferior shell." #+begin_src emacs-lisp (defun gcr/shell-mode-hook () "Personalizations." (interactive) (turn-on-smartparens-strict-mode) (turn-on-pretty-mode) (gcr/disable-tabs) (fci-mode) (whitespace-turn-on) (visual-line-mode) (hs-minor-mode 1) (local-set-key (kbd "RET") 'newline-and-indent)) (add-hook 'shell-mode-hook 'gcr/shell-mode-hook) #+end_src ** Standard ML (SML) [fn:eb5c01ac: https://en.wikipedia.org/wiki/Standard_ML] =sml-mode= has its documentation here [fn:e31e1b22: http://www.smlnj.org/doc/Emacs/sml-mode.html] and package here [fn:185e62bd: http://elpa.gnu.org/packages/sml-mode.html]. I am not shy about including stuff that defaults fine in the mode when its purpose is to educate the reader who /doesn't/ bother to read the mode definition. #+begin_src emacs-lisp (require 'sml-mode) (defun gcr/sml-mode-hook () "Personal settings." (interactive) (turn-on-pretty-mode) (turn-on-smartparens-strict-mode) (local-set-key (kbd "RET") 'newline-and-indent) (gcr/untabify-buffer-hook) (gcr/disable-tabs) (fci-mode) (hs-minor-mode 1) (visual-line-mode)) (add-hook 'sml-mode-hook 'gcr/sml-mode-hook) (setq sml-indent-level 2) (setq sml-rightalign-and t) (setq sml-electric-pipe-mode t) (setq sml-program-name "sml") #+end_src =pretty-mode= will give us Unicode symbols for arrows and stuff, so this mode doesn't need to handle it. #+begin_src emacs-lisp (setq sml-font-lock-symbols nil) #+end_src When SML starts up, it loads =sml-config-file= by default. Perhaps some day I would have such a prelude. =sml-max-name-components= is kind of interesting… I will assume that it is fine for now because until I know better, it is. Like all programming modes… save everything before evaluating code. #+begin_src emacs-lisp (defadvice sml-prog-proc-load-file (before beforesml-prog-proc-load-file activate) (gcr/save-all-file-buffers)) #+end_src ** Strings Sometimes we keep code inside of strings inside of another language. HQL for example. Make it easy to edit those strings without worrying about escaping everything. String-edit provides a nice helper here. ** Structured Query Language (SQL) [fn:a018350e: https://en.wikipedia.org/wiki/SQL] Sometimes it is really nice to have SQL keywords written all upper-case. Seriously. Although it is kind of a learning-phase where you must do that, you really grow out of it at some point. Despite that, sometimes it is nice to have. =slqup-mode= [fn:be68b5d2: https://github.com/Trevoke/sqlup-mode.el] does just this for you. I love the package definition: #+begin_quote Its sole purpose is to make your life easier when writing SQL. #+end_quote What a great goal! #+begin_src emacs-lisp (require 'sqlup-mode) #+end_src There is a =sql-mode= [fn:e151d946: http://www.emacswiki.org/emacs/SqlMode] of course, and surely I will need to set it up one day. ** Table Tables don't sound that exciting, but try running the world without a tabular data representation! Not so easy huh? SAKURAI Masashi has made it easy for us in Emacs with =ctable=. #+begin_src emacs-lisp (require 'ctable) (defun gcr/ctbl:table-mode-hook () "Personal customization" (interactive)) (add-hook 'ctbl:table-mode-hook 'gcr/ctbl:table-mode-hook) #+end_src ** TeX [fn:5bb50e18: https://en.wikipedia.org/wiki/TeX] / LaTeX [fn:a13f106f: [[https://en.wikipedia.org/wiki/LaTeX]]] / ConTeXt [fn:8a78f8ab: https://en.wikipedia.org/wiki/ConTeXt] AUCT_{E}X is the mode that makes it possible to work with all of these fine tools. Visiting their website I took their advice of reading the Info document in Emacs by first installing it via Homebrew. That was my mistake since the prerequisites page starts by explaining that this mode is 100% Elisp and that you should use ELPA to install it. I started over again with the setup. When you read the documentation, the first page explains how to load the mode and associate files with modes but you should ignore that because when you configure it via ELPA, everything "just works". Installation mostly involved the prerequisites. This version of Emacs is modern. For TeX, on Linux, I've always used TeX Live [fn:841d4205: https://www.tug.org/texlive/] and on OSX I've always used MacTeX [fn:490cc248: https://www.tug.org/mactex/]. Ghostscript comes with both either via =apt-get= or =homebrew=. =texinfo= didn't seem necessary so I did not pursue installing it. Enable most of the stuff we need, given that I don't yet know what we need but the manual helps us here. #+begin_src emacs-lisp (setq TeX-auto-save t) (setq TeX-parse-self t) #+end_src The "Quick Start" lists the most frequent operations, and I think that I will get the PDF for them. Looking at just this tiny, tiny bit of effort to get AUCTeX working… it is just so inspiring to see the plethora of amazingly wonderful tools out there /free/ for all to use. For a start, I will just do some basic stuff that I do for most modes. #+begin_src emacs-lisp (defun gcr/TeX-mode-hook () "Settings applicable to every AUCTeX supported mode." (interactive) (turn-on-smartparens-strict-mode) (gcr/disable-tabs) (fci-mode) (linum-mode)) (add-hook 'TeX-mode-hook 'gcr/TeX-mode-hook) #+end_src Enable parse on load. #+begin_src emacs-lisp (setq TeX-parse-self t) ; #+end_src Enable parse on save. #+begin_src emacs-lisp (setq TeX-auto-save t) ; #+end_src Never save tabs because AUCTeX has a hard time with them. #+begin_src emacs-lisp (setq TeX-auto-untabify t) #+end_src Before letting this mode process any file, save all buffers: #+begin_src emacs-lisp (defadvice TeX-command-master (before before-TeX-command-master activate) (gcr/save-all-file-buffers)) #+end_src My typical preference is to easily work with XDVI during development and PDF for deployment. My want had been to turn PDF generation on, while at the same time still producing a DVI file. To do that, I did something like this: #+begin_src emacs-lisp (setq TeX-PDF-mode +1) (setq TeX-DVI-via-PDFTeX +1) #+end_src Don't prompt me every time I run =C-c C-c= about saving the file, instead, just save it [fn:b2655f5c: http://mbork.pl/2015-01-10_A_few_random_Emacs_tips]. #+begin_src emacs-lisp (setq TeX-save-query nil) #+end_src Start the proper mode for LCO files. #+begin_src emacs-lisp (add-to-list 'auto-mode-alist '("\\.lco?\\'" . TeX-latex-mode)) #+end_src ** Text #+begin_src emacs-lisp (defun gcr/text-mode-hook () (fci-mode) (visual-line-mode) (gcr/untabify-buffer-hook)) (add-hook 'text-mode-hook 'gcr/text-mode-hook) #+end_src ** Vagrant [fn:a83cf3b8: http://www.vagrantup.com/] Vagrant is quite nice. Perhaps a bit preemptively, I'm trying to get Emacs setup nice for what I already know I must do. This belongs in this heading I believe: #+begin_src emacs-lisp (add-to-list 'auto-mode-alist '("Vagrantfile$" . ruby-mode)) #+end_src Nice package [fn:ccaa2275: https://github.com/ottbot/vagrant.el] for working with Vagrant; hundreds of people already using it. No configuration even necessary. ** Web [fn:857fba7f: https://en.wikipedia.org/wiki/HTML] JSON support is included here, too. As you go about your business you read about features that seem nice or you really didn't actively think about. One such opportunity/mistake I am guilty of is using various web-based tools to accomplish thing for example formatting a JSON string, like this ={"foo":10, "bar":20, "baz":50}= example. For whatever reason, that is always just the way that I had done it. Reading irreal a nice option/reminder was posted for a JSON formatter [fn:9d35fd56: https://github.com/gongo/json-reformat] #+begin_src emacs-lisp (require 'web-mode) (setq web-mode-enable-block-partial-invalidation t) (setq web-mode-engines-alist '(("ctemplate" . "\\.html$"))) (defun gcr/web-mode-hook () (whitespace-turn-off) (rainbow-turn-off) (visual-line-mode) (local-set-key (kbd "RET") 'newline-and-indent) (setq web-mode-markup-indent-offset 2) (setq web-mode-css-indent-offset 2) (setq web-mode-code-indent-offset 2) (setq web-mode-indent-style 2) (setq web-mode-style-padding 1) (setq web-mode-script-padding 1) (setq web-mode-block-padding 0) (gcr/untabify-buffer-hook)) (add-hook 'web-mode-hook 'gcr/web-mode-hook) (require 'json-reformat) (add-to-list 'auto-mode-alist '("\\.html?\\'" . web-mode)) (add-to-list 'auto-mode-alist '("\\.json\\'" . web-mode)) (add-to-list 'auto-mode-alist '("\\.phtml\\'" . web-mode)) (add-to-list 'auto-mode-alist '("\\.tpl\\.php\\'" . web-mode)) (add-to-list 'auto-mode-alist '("\\.[agj]sp\\'" . web-mode)) (add-to-list 'auto-mode-alist '("\\.as[cp]x\\'" . web-mode)) (add-to-list 'auto-mode-alist '("\\.erb\\'" . web-mode)) (add-to-list 'auto-mode-alist '("\\.mustache\\'" . web-mode)) (add-to-list 'auto-mode-alist '("\\.djhtml\\'" . web-mode)) #+end_src ** Web browsing Browse URLs in a real browser; nothing against W3C. [fn:44dd271e: https://www.gnu.org/software/emacs/manual/html_node/emacs/Browse_002dURL.html] EWW looks interesting, too [fn:4c24a298: http://lars.ingebrigtsen.no/2013/06/16/eww/] #+begin_src emacs-lisp (setq browse-url-browser-function 'browse-url-generic) (gcr/on-gnu/linux (setq browse-url-generic-program "chromium-browser")) (gcr/on-osx (setq browse-url-browser-function 'browse-url-default-macosx-browser) (require 'osx-browse) (osx-browse-mode 1)) (gcr/on-windows (setq browse-url-browser-function 'browse-url-default-windows-browser)) #+end_src Searching for things on the world wide web is a daily occurrence. There are a lot of helper functions out there to search Google, but there is a package that does it all, and this is it: #+begin_src emacs-lisp (require 'google-this) (google-this-mode 1) (gcr/diminish 'google-this-mode) #+end_src ** TRAMP [fn:4997f5f8: https://www.gnu.org/software/tramp/] TRAMP stands for "Transparent Remote (file) Access, Multiple Protocol". It is really, really beautiful. #+begin_src emacs-lisp (setq tramp-default-user "gcr") (setq tramp-default-method "ssh") #+end_src ** YAML Thank you, Kitchenplan. #+begin_src emacs-lisp (require 'yaml-mode) (add-to-list 'auto-mode-alist '("\\.yml$" . yaml-mode)) (add-to-list 'auto-mode-alist '("\\.yaml$" . yaml-mode)) (defun gcr/yaml-mode-hook () "Helpful behavior for YAML buffers." (interactive) (turn-on-smartparens-strict-mode) (local-set-key (kbd "RET") 'newline-and-indent) (gcr/disable-tabs) (turn-on-pretty-mode) (gcr/untabify-buffer) (fci-mode) (hs-minor-mode 1) (linum-mode) (visual-line-mode)) #+end_src ** Diagramming, UML creation, Workflow How you perform these tasks is entirely up to you. There are a lot of good options both inside and outside of Emacs. For the general cases, I like the ones that are built in and play nice, especially with org-mode. At its simplest, artist-mode [fn:5f9306fa: http://www.emacswiki.org/emacs/ArtistMode] is plenty fine for diagramming and stuff. Graphviz also works well [fn:93e16211: http://www.graphviz.org/]. Ditaa is sort of the next level up [fn:b6f5f0cc: http://ditaa.sourceforge.net/], and finally PlantUML [fn:245: http://plantuml.sourceforge.net/]. They are all good options at different times, and they all work with org-mode. Everything I will publish will go through org-mode. org-mode just shines so, so brightly. As of writing, I'm undecided NOW how best to standardizing on a solution in this area. The good thing is that each tool is a good fit depending upon what you want to accomplish: - artist-mode: Anything in ultra portable text, ASCII or UTF-8, just works. - Graphviz: Graphically and lays things out automatically. - Ditaa: Graphical but based on ASCII diagrams. - PlantUML: Includes full breadth of UML options, everything: sequence, use case, class, activity, component, state, and object. - [[https://github.com/tj64/puml][This]] may help ditaa was my first pick for usage for the blaring simplicity and power of it. org-mode provides a setup [fn:69c0caad: http://orgmode.org/worg/org-contrib/babel/languages/ob-doc-ditaa.html]document that I followed. It required installing a JRE and that was about it. artist-mode is automatically loaded for the source block. The example below; thank you [fn:c8388777: http://www.craiglarman.com/wiki/index.php?title=Books_by_Craig_Larman] Craig Larman #+begin_src ditaa :file ./images/auap.png :noweb-ref no-tangle +----------+1 1…3+------+ | Sailboat +◆----------+ Mast | +-----+----+ +------+ ◆1 | | 1…2+------+ +----------------+ Hull | +------+ This is not a sailboat #+end_src #+RESULTS: [[file:./images/auap.png]] This [fn:cb5475bf: http://www.gnuvola.org/software/aa2u/] =ascii-art-to-unicode= tool also is interesting. Sparkline graphs [fn:8d44474a: http://en.wikipedia.org/wiki/Sparkline] look interesting. Although I'm not sure where or how I will use them right now, I want them to be available when the time is right. Also I am curious about where they may fit in =org=. #+begin_src emacs-lisp (require 'sparkline) #+end_src *** Setup **** ditaa The =ditaa= library file is not version controlled. #+begin_src emacs-lisp (defconst gcr/ditaa-jar (concat (getenv "EELIB") "/ditaa0_9.jar")) (defun gcr/warn-ditaa-jar () "Warn of ditaa misconfiguration." (interactive) (unless (f-exists? gcr/ditaa-jar) (warn "Can't seem to find a ditaa jar where it was expected at: %S. Ditaa will not function without it. Download a copy here: http://sourceforge.net/projects/ditaa/" gcr/ditaa-jar))) (gcr/warn-ditaa-jar) (setq org-ditaa-jar-path gcr/ditaa-jar) #+end_src #+begin_src emacs-lisp (add-to-list 'auto-mode-alist '("\\.asc" . artist-mode)) (add-to-list 'auto-mode-alist '("\\.art" . artist-mode)) (add-to-list 'auto-mode-alist '("\\.asc" . artist-mode)) #+end_src **** plantuml =plantuml= needs a full directory path. It is easier to address it here. #+begin_src emacs-lisp (defconst gcr/plantuml-jar (concat (expand-file-name (getenv "EELIB")) "/plantuml.8026.jar")) #+end_src The rest of the configuration is vanilla. #+begin_src emacs-lisp (defun gcr/warn-plantuml-jar () "Warn of plantuml misconfiguration." (interactive) (unless (f-exists? gcr/plantuml-jar) (warn "Can't seem to find a plantuml jar where it was expected at: %S. Plantuml will not function without it. Download a copy here: http://plantuml.sourceforge.net/" gcr/plantuml-jar))) (gcr/warn-plantuml-jar) (setq plantuml-jar-path gcr/plantuml-jar) (require 'plantuml-mode) (eval-after-load "ob-plantuml" (setq org-plantuml-jar-path gcr/plantuml-jar)) (defun gcr/plantuml-mode-hook () "Personal settings." (interactive) (turn-on-pretty-mode) (turn-on-smartparens-strict-mode) (local-set-key (kbd "RET") 'newline-and-indent) (gcr/untabify-buffer-hook) (gcr/disable-tabs) (fci-mode) (hs-minor-mode 1) (linum-mode) (wrap-region-mode t) (turn-on-stripe-table-mode)) (add-hook 'plantuml-mode-hook 'gcr/plantuml-mode-hook) #+end_src Just read the user manual: Note to self, for any image generation keep in mind how this #+begin_example (org-display-inline-images nil t) #+end_example is being used. =org= has hook for post rendering so Emacs is always up to date. In this mode I have no such solution, so I will probably forget while inside. - Sequence diagrams - Very feature rich - Images immediately convey a lot of information about the tool here - Chose a simple example, no all encompassing - Tested, worked #+begin_src plantuml :file ./images/pumlseqd.png :noweb-ref ignore :exports results Alice -> Bob: Authentication Request Bob --> Alice: Authentication Response Alice -> Bob: Another authentication Request Alice <-- Bob: another authentication Response #+end_src #+NAME: [[file:./images/pumlseqd.png]] - Use case diagrams - Actor variable aliasing, very thoughtful - Tested, worked #+begin_src plantuml :file ./images/pumlucd.png :noweb-ref ignore :exports results left to right direction skinparam packageStyle rect actor customer actor clerk rectangle checkout { customer -- (checkout) (checkout) .> (payment) : include (help) .> (checkout) : extends (checkout) -- clerk } #+end_src #+NAME: [[file:./images/pumlucd.png]] - Class diagram - Value this greatly for all sorts of ideas not just classes - =hode=, =show=, and =include= are mentioned - Could be a great reuse mechanism combined with noweb and tangling - Spotted characters might be useful to indicating other things - Example is data which is clearly a first-class citizen - Six package visualization types - Packaging vs. namespaceing is nice - Good support for splitting large images among output pages - Tested, works, added TODO for =org-display-images-call= after generation #+begin_src plantuml :file ./images/pumlcd.png :noweb-ref ignore :exports results title This is not a sailboat scale 200 width Sailboat "1" *-- "1..3" Mast Sailboat "1" *-- "1..3" Hull #+end_src #+NAME: [[file:./images/pumlcd.png]] - Activity diagrams - May indicate top to bottom flow using =top= - May label arrows - May force arrow direction - Sweet if/else structure for branching - Partition construct looks very useful - New syntax [fn:e81de35c: http://plantuml.sourceforge.net/activity2.html] seems good and there are more examples - Next chapter covers the new syntax, so using that - Tested, works #+begin_src plantuml :file ./images/pumlad.png :noweb-ref ignore :exports results start partition Initialization { :read config file; :init internal variable; } partition Running { :wait for user interaction; :print information; } stop #+end_src #+NAME: [[file:./images/pumlad.png]] - Component diagrams - Might be good to use the names to define all of the diagram entity types - Need to find out what is "modern" UML, or at least, modern for me - Might be a nice summary tool - Tested, works #+begin_src plantuml :file ./images/pumlcod.png :noweb-ref ignore :exports results [First component] [Another component] () "First Interface" () "Another interface" as Interf2 DataAccess - [First Component] [First Component] ..> HTTP : use #+end_src #+NAME: [[file:./images/pumlcod.png]] - State diagrams - Such a sweet tool - Works OK #+begin_src plantuml :file ./images/pumlstd.png :noweb-ref ignore :exports results [*] --> State1 State1 --> [*] State1 : this is a string State1 : this is another string #+end_src #+NAME: [[file:./images/pumlstd.png]] - Object diagrams - How different from class? - Works, all stuff is there but I didn't bring it #+begin_src plantuml :file ./images/pumlod.png :noweb-ref ignore :exports results object Object01 object Object02 Object01 <|-- Object02 #+end_src #+NAME: [[file:./images/pumlod.png]] - Commands - Header and footer values - Zoom level - Creole markup for most text elements - Lists, and sub-lists - Horizontal lines, will appears in most containers - Headings - Plain old HTML - Tables, LaTeX style - OpenIconic icons [fn:2f694b60: https://useiconic.com/open] anywhere - For fonts and colors - You can change just about everything - You may nest definitions, nice - =monochrome true= option - Nice if you are printing - Or just don't want any colors anyway - Internationalization - Full Unicode character support * Libraries :PROPERTIES: :noweb-ref: Libraries :END: ** Generally nice - Dash / Dash-Functional Not totally sure where this belongs, but dash [fn:9d300103: https://github.com/magnars/dash.el] is something that a lot of the packages I use require, and it is an excellent library, so it needs recognition in this document. #+begin_src emacs-lisp (eval-after-load "dash" '(dash-enable-font-lock)) #+end_src - f [fn:dc91c0cb: https://github.com/rejeep/f.el] #+begin_src emacs-lisp (require 'f) #+end_src Use the API to indicte things /to the reader/: - =f-exists?= vs. =f-symlink?= Because *I* can't seem to remember this critical and key detail on how files work, here is an example. It says: - Every symlink is a file - Every file is not a symlink #+begin_src emacs-lisp :noweb-ref no-tangle (setq a-tmp-file (make-temp-file "~/")) (setq a-tmp-link (concat a-tmp-file "-LINK")) (make-symbolic-link a-tmp-file a-tmp-link 'overwrite) (print (setq no-file "/infinity")) (print (f-exists? no-file)) (print a-tmp-file) (print (f-exists? a-tmp-file)) (print (f-file? a-tmp-file)) (print (f-symlink? a-tmp-file)) (print a-tmp-link) (print (f-exists? a-tmp-link)) (print (f-file? a-tmp-link)) (print (f-symlink? a-tmp-link)) #+end_src #+RESULTS: #+begin_example "/infinity" nil "/Users/gcr/3655Wbk" t t nil "/Users/gcr/3655Wbk-LINK" t t t #+end_example - s [fn:017b522b: https://github.com/magnars/s.el] Starting to think that I might want a "useful library" section, because I just added the =xml-rpc= [fn:0c0b84fd: http://melpa.milkbox.net/#/xml-rpc] library here because it is clearly useful: #+begin_src emacs-lisp (require 'xml-rpc) #+end_src metaweblog is necessary for org2blog, too: #+begin_src emacs-lisp (require 'metaweblog) #+end_src - Various - =uuid= - Make it easy to get some. Somes you really need them! #+begin_src emacs-lisp (require 'uuid) #+end_src ** Built-in pcase [fn:e76be200: http://www.emacswiki.org/emacs/PatternMatching] provides pattern-matching macros. This is very nice whether you've already used something like this before, or not! ** Characters / Unicode unidecode [fn:2a08dd99: https://github.com/sindikat/unidecode] does its best to convert UTF-8 to ASCII; then I found that it wouldn't load so I removed it. If you've verused a character terminal then you already know that figlet [fn:81c97c99: http://www.figlet.org/] is a mandatory tool. This [fn:08208a82: https://bitbucket.org/jpkotta/figlet] package makes it nice to use. It has all the stuff you /would/ want to do, like figletify stuff. It even has a little helper function to show you how the fonts look… beccause you /know/ that you would have ended up writing something like that yourself if it wreren't here: #+begin_src emacs-lisp (require 'figlet) #+end_src Make sure =figlet= may be found on OSX via Brew. #+begin_src emacs-lisp (setq figlet-font-directory "/usr/local/bin/") #+end_src * Jokes :PROPERTIES: :noweb-ref: Jokes :END: These are things that I consider critical to keeping things light-hearted. #+begin_src emacs-lisp (require 'nyan-mode) #+end_src Make it look like you are typing at light speed. I had to start =calculator-mode= before running this in order for it to be happy. #+begin_src emacs-lisp (require 'highlight-tail) #+end_src Take "zoning out" to a whole new level. #+begin_src emacs-lisp (require 'zone) #+end_src For when you want to watch /someone else/ play Tetris instead of yourself, call =autotetris=. * Customize :PROPERTIES: :noweb-ref: Customize :END: *This must come before manually set variables* This approach needs further research as it seems to work but I am not sure what kind of trouble I could cause by doing this so I know that it may cause some such trouble! For example, sometimes values I set in here get stomped on. That is probably because the call to =custom-set-variables= occurs /after/ the packages are loaded specifying them. Right now I am still not totally sure because of =eval-after-load= blocks. #+begin_src emacs-lisp (custom-set-variables ;; custom-set-variables was added by Custom. ;; If you edit it by hand, you could mess it up, so be careful. ;; Your init file should contain only one such instance. ;; If there is more than one, they won't work right. '(custom-safe-themes (quote ("8aebf25556399b58091e533e455dd50a6a9cba958cc4ebb0aab175863c25b9a4" default))) '(display-time-world-list (quote (("America/Chicago" "Chicago") ("Asia/Kolkata" "Kolkata") ("Asia/Kuala_Lumpur" "Kuala Lumpur")))) '(ess-R-font-lock-keywords (quote ((ess-R-fl-keyword:modifiers . t) (ess-R-fl-keyword:fun-defs . t) (ess-R-fl-keyword:keywords . t) (ess-R-fl-keyword:assign-ops . t) (ess-R-fl-keyword:constants . t) (ess-fl-keyword:fun-calls) (ess-fl-keyword:numbers) (ess-fl-keyword:operators) (ess-fl-keyword:delimiters) (ess-fl-keyword:= . t) (ess-R-fl-keyword:F&T)))) '(inferior-R-font-lock-keywords (quote ((ess-S-fl-keyword:prompt . t) (ess-R-fl-keyword:messages . t) (ess-R-fl-keyword:modifiers . t) (ess-R-fl-keyword:fun-defs . t) (ess-R-fl-keyword:keywords . t) (ess-R-fl-keyword:assign-ops . t) (ess-R-fl-keyword:constants . t) (ess-fl-keyword:matrix-labels . t) (ess-fl-keyword:fun-calls) (ess-fl-keyword:numbers) (ess-fl-keyword:operators) (ess-fl-keyword:delimiters) (ess-fl-keyword:= . t) (ess-R-fl-keyword:F&T)))) '(linum-format "%5d") '(osx-browse-guess-keystrokes (quote ("s-b k"))) '(osx-browse-url-keystrokes (quote ("s-b u")))) (custom-set-faces ;; custom-set-faces was added by Custom. ;; If you edit it by hand, you could mess it up, so be careful. ;; Your init file should contain only one such instance. ;; If there is more than one, they won't work right. '(anzu-mode-line ((t (:foreground "#073642" :weight bold))))) #+end_src * Tangling ** .emacs.el My document style does not let itself to tangling-comments. #+begin_src emacs-lisp :tangle .emacs.el :comments no «Start-Up» «Customize» «Runtime-Check» «Provisioning» «Means» «Keybindings» (gcr/on-windows «Windows-Helper-Bindings») «Modes» «Libraries» «Jokes» #+end_src ** eshell/alias This file can't contain comment lines in =sh= or =emacs-lisp= and I don't want to find out why so don't include =org= comments. Be sure to link =~/.emacs.d/eshell= here. #+begin_src sh :tangle eshell/alias :comments no alias bbc ~/git/github-grettke/stathon/stathon.py ~/git/bitbucket-grettke/ | grep True alias clear recenter 0 alias d 'dired $1' alias ff find-file $1 alias g git $* alias gb git branch $* alias gbc ~/git/github-grettke/stathon/stathon.py ~/git/github-grettke/ | grep True alias gco git checkout $* alias gpom git push origin master alias gst git status alias la ls -lha $* alias ll ls -lh $* alias s ssh $* alias top proced #+end_src * Portability Portability is a trait of something that may be easily moved. Here it is between operating systems. The =gcr/on= prefixed functions have provided portability just fine until now. Now I am spending a lot more tim working on Windows and my existing setup *reduced* by ability to realize the goals of this sytem. The fastest way to define the deficits in my setup is to simply address the solutions. They follow. ** Windows - Install the 32bit Emacs distribution straight from GNU - There are others. Do not use them. - Extract it to =~/apps= and add the =bin= dir to the exported =PATH= - Export =HOME= set to your preference - Your home dir =C:\Users\user= works fine - Run =addpm= to add Emacs to the application menu - Install [[http://sourceforge.net/projects/ezwinports/][EZWinPorts]] - Want normal Windows users to have a chance so not using MSYS or CYGWIN - Stuff to install - GNUTLS - LibPNG - make with guile - Install [[http://aspell.net/win32/][Aspell Win32]] - Add to PATH - Install the English dictionary - Installer /should/ successfully identify the Aspell install directory and install the =dict= and =data= into the corect location - Keyboard setup - Goal was to utilize my current keybindings and make no changes - This system uses Super all over the place and maps the WindowsKey to Super - Windows maps a number of actions to WindowsKey - A Windows configuration is /supposed/ to remove those bindings, but it does not. They conflict with my existing bindings and I wasn't going to change after using them for one year. After spending 4 hours trying to find a work around, I pursued a more simplistic strategy that is defined in a code block under this heading - [[http://www.graphviz.org/Download..php][Graphviz]] - Grabbed from their home page - Installed via the MSI - Added bin dir to path - Install [[http://imagemagick.org/][ImageMagick]] There are many options for keymapping in Windows. [[https://code.google.com/p/keymapper/][KeyMapper]] and [[https://sharpkeys.codeplex.com/][SharpKeys]] used to satisfy my requirements, but then quit doing so. Quite simply, they did not work /for me/ on Windows 8.1 despite having worked fine for years on 7. [[http://www.autohotkey.com/][AutoHotKey]] (AHK) now performs the task correctly. I need to do the simplest possible thing here. I /want/ to do it /the right way/ and just deal with low-level key-codes, but that is a poor use of time so I am not. I wanted to figure how to to use AHK to make Enter send Enter when pushed once and to make it act as the Control key when held. I didn't have enough time so I am making my RightShift key act as Enter. I will post to the forums to find out how. To avoid generating key combinations that activate the default Windows keybinding events I am using a super simple strategy of and where: - Make WindowsKey act as to Super - Issue is that Super keybindings activate default Windows actions - Solution is to make WindowsKey instead send MetaSuper - *Control-super* does not work and I don't know why - That is why I am using Meta here - In this sytem must define additional keybindings "on Windows" that do the the same thing with the new =M-s-= bindings - This heading exists to define both - For now doing it manually, no automation, no reuse, just fix what doesn't work GitForWindows seems to work fine adding the *safe* stuff to the PATH, but not more. Emacs gets started with =runemacs= and picks up the =PATH= correctly. =vc= works fine but =magit= does not. I will investigate this. Thus far, swapping capslock with leftcontrol and enter with rightcontrol has been pleasant. It is very doable since Windows keyboards have all of the required controls! The Macbook, though, does not, hence the need for the program to make enter perform double-duty. It would be really great if we had that on Windows too. After spending a combined six hours or so looking at approaches and evaluating them I didn't find one that I worked. At that point, I felt that it was no longer a valuable pursuit. As such, on Winboxen I'll go with this and on Macs I'll go with that. Simpler. For the record, some researched areas: - All of the site literature - Really, really work reading - Feels haphazard but it will make sense after reading it all - Searched all forum posts for similar needs - [[http://www.autohotkey.com/board/topic/103044-one-key-acting-as-a-modifier-but-also-as-a-hotkey/?hl%3D%252Bemacs#entry637897][One key acting as a modifier but also as a hotkey]] - Exactly what I want - Not exactly what I need - [[http://www.autohotkey.com/board/topic/113282-emacs-pincky/?hl%3D%252Bemacs#entry662239][emacs pincky]] - Good to know - Doens't work - [[https://github.com/boblu/EmacsEverywhere/blob/master/EmacsEverywhere.ahk][emacseverywhere]] - Nice to know - Not exactly what I want - http://www.autohotkey.com/docs/Tutorial.htmTutorial - Talked about how to handle a key press, using a loop - Interesting because that is definitely "one way" and there are others - Eg: The following example clicks the left mouse button repeatedly while the user is holding down the F1 key - Hotkeys talked about how to get a key to do one thing when held and released and another when using in combinationt - At least how I am reading it - Here is the whole example - Still not what I need #+begin_quote You can define a custom combination of two keys (except joystick buttons) by using " & " between them. In the below example, you would hold down Numpad0 then press the second key to trigger the hotkey: #+end_quote #+begin_src sh Numpad0 & Numpad1::MsgBox You pressed Numpad1 while holding down Numpad0. Numpad0 & Numpad2::Run Notepad #+end_src #+begin_quote In the above example, Numpad0 becomes a prefix key; but this also causes Numpad0 to lose its original/native function when it is pressed by itself. To avoid this, a script may configure Numpad0 to perform a new action such as one of the following: #+end_quote #+begin_src sh Numpad0::WinMaximize A ; Maximize the active/foreground window. Numpad0::Send {Numpad0} ; Make the release of Numpad0 produce a Numpad0 keystroke. #+end_src #+begin_quote The presence of one of the above hotkeys causes the release of Numpad0 to perform the indicated action, but only if you did not press any other keys while Numpad0 was being held down. #+end_quote Since I can't be the /only/ Emacs Windows user would like something like this for the Windows Emacs build, there could be an opportunity to group-sponsor the addition to AHK. Right now I am not pursuing leading such an effort. Perhaps you are? If you are connecting to a Windows box from an OSX box running Karabiner using Microsoft Remote Desktop then you must disable AHK. You won't be able to use the key. *** Testing - Windows 7 - No installation issues - Works perfectly - Windows 8.1 - Package installation issues both for Package and ElGet - Unsure, will do more testing *** Helper Bindings :PROPERTIES: :noweb-ref: Windows-Helper-Bindings :END: YAS. #+begin_src emacs-lisp (defun gcr/ymh-h () (define-key yas-minor-mode-map (kbd "M-s-4") 'yas-expand)) (add-hook 'yas-minor-mode-hook 'gcr/ymh-h) #+end_src ESS ignore until needed. ORG. #+begin_src emacs-lisp (defun gcr/omh-h () (local-set-key (kbd "M-s-h") 'org-babel-check-src-block) (local-set-key (kbd "M-s-i") 'org-babel-insert-header-arg) (local-set-key (kbd "M-s-j") 'org-babel-previous-src-block) (local-set-key (kbd "M-s-k") 'org-babel-next-src-block) (local-set-key (kbd "M-s-l") 'org-babel-demarcate-block) (local-set-key (kbd "M-s-;") 'org-babel-view-src-block-info) (local-set-key (kbd "M-s-b s") 'org-babel-switch-to-session) (local-set-key (kbd "M-s-b c") 'org-babel-switch-to-session-with-code) (local-set-key (kbd "M-s-o") 'org-babel-execute-maybe) (local-set-key (kbd "M-s-t") 'org-babel-tangle) (local-set-key (kbd "M-s-x") 'org-babel-do-key-sequence-in-edit-buffer) (local-set-key (kbd "M-s-w w") 'org-export-dispatch) (local-set-key (kbd "M-s-") 'org-babel-execute-buffer) (local-set-key (kbd "M-s-i d") 'org-display-inline-images) (local-set-key (kbd "M-s-i r") 'org-remove-inline-images)) (add-hook 'org-mode-hook 'gcr/omh-h) #+end_src Emacs-lisp. #+begin_src emacs-lisp (defun gcr/emh-h () (local-set-key (kbd "M-s-l eb") 'gcr/elisp-eval-buffer) (local-set-key (kbd "M-s-l ep") 'eval-print-last-sexp) (local-set-key (kbd "M-s-l td") 'toggle-debug-on-error) (local-set-key (kbd "M-s-l mef") 'macroexpand) (local-set-key (kbd "M-s-l mea") 'macroexpand-all) (local-set-key (kbd "M-s-p") 'gcr/describe-thing-in-popup) ) #+end_src Various. #+begin_src emacs-lisp (global-set-key (kbd "M-s-d h") 'diff-hl-mode) (global-set-key (kbd "M-s-d e") 'vc-ediff) (global-set-key (kbd "M-s-d d") 'vc-diff) (global-set-key (kbd "M-s-d u") 'vc-revert) (global-set-key (kbd "M-s-2") 'gcr/two-key-map) (global-set-key (kbd "M-s-p") 'gcr/describe-thing-in-popup) (global-set-key (kbd "M-s-") 'gcr/smart-open-line) (global-set-key (kbd "M-s-7") 'gcr/insert-timestamp*) (global-set-key (kbd "M-s-") 'gcr/text-scale-increase) (global-set-key (kbd "M-s-") 'enlarge-window) (global-set-key (kbd "M-s-") 'shrink-window) (global-set-key (kbd "M-s-") 'enlarge-window-horizontally) (global-set-key (kbd "M-s-") 'shrink-window-horizontally) #+end_src Polymode ignore until needed. *** AutoHotKey AHK has been fragile in these ways: - Wheel even mapping works fine for a day and quits working - It hasn't worked since - Putting the configuration file in =~/Documents= works - Putting it in =~/= does not work - Sometimes the left control and caps-lock swap gets reversed - Observations - Using this setup worked perfectly for a while because I used it only on my home machine - Once I used it for a while at work that changed everything because - The keyboard was layed out differently - 99% of my work was inside of VMWare - With that in mind I set up the two different profiles - They need to be refactored, and splitting them up is the first step - AHK seems to make itself when running both in the host and in a guest VM - The caps-lock swap often becomes confused and the caps lock turns on causing hilarious consequences - For this reason, there are two configurations - One for Windows "on the metal" - One for Windows "on a VM" Fixes: - Rebooting [[http://www.autohotkey.com/docs/Hotkeys.htm][Hotkey documentation.]] - =#=: Windows logo key - =!=: Alt - =^=: Control - ~+~: Shift I could not disable the Windows key on Windows 7. I made many attempts and all failed. When I try some s-l and lock the screen I need to remember that I've got a binding on M-s-l. That patterns remains the same. The bindings that I removed follow: the correct binding and a failed remedy. The problem is that Windows processes the key events before they reach AHK. **** Common Config :PROPERTIES: :noweb-ref: AutoHotKey-Common-Config :END: #+begin_src sh Capslock::LCtrl LCtrl::CapsLock Enter::RCtrl ,*RCtrl::Enter ,*AppsKey::Enter #b::!#b #d::!#d #e::!#e #l::!#l #p::!#p #t::!#t ^+l::#l #+end_src **** OTM Config #+begin_src src :tangle AutoHotKeyOTM.ahk :comments no WheelUp:: Send {WheelDown} Return WheelDown:: Send {WheelUp} Return «AutoHotKey-Common-Config» #+end_src **** OAV Config After months of trial and error, I decided that I will make this work. What I mean is that the bindings should be the same whether AHK is running OTM or OAV. The one thing that never seems to work is the these wheel mouse bindings. So, they are in OTM and not OAV. This is good because they are nearly identical. #+begin_src src :tangle AutoHotKeyOAV.ahk :comments no «AutoHotKey-Common-Config» #+end_src ** OSX [[https://pqrs.org/osx/karabiner/][Karabiner]] provides a quite perfect /Return to Control_L (+ When you type Return only, send Return)/ to make the return key send "return" when struck and released and to act as the "control" key when held and chorded. *** Keyboard - Use all F keys as standard function keys: yes Modifier keys: - caps lock \rarr control - control \rarr caps lock - option \rarr option (apple style) - command \rarr command (apple style) - Shortcuts Alone, F11 and F12 =Apple->System Preferences->Keyboard->Shortcuts->Mission Control= un-check "Show Desktop" =F11= and "Show Dashboard" =F12=. Mission Control, F1 and F8 =Apple->System Preferences->Keyboard->Shortcuts->Keyboard= un-check "Turn keyboard access on or off" =^F1= and "Move focus to status menus" =^F8=. - <2015-03-29 Sun> - Better yet, [[https://github.com/grettke/osx-provision][automate]] most of this. * Reminders - *NEVER* edit source blocks outside of their editor mode - *Guaranteed* issues will occur if it is LISP - Treat source blocks amazingly delicately and thoughtfully because if you don't then you will break your system - The flow is - First make the new changes directly in the code - Verify that they work - *Then* place them in this document - Only use in-line footnotes unless your document is very very small - Footnotes in org-mode are really, really great. Before you really get into using them, take a bit of time to think about how you want to use them. - If you have 5 footnotes or less, then don't think anymore about it. If more then read on. - This topic is not unique to org first of all, it just isn't something that you consider much until it is too late. Once you get into the org life-cycle, you start tossing and slinging document and code fragments with ease, especially while re-factoring. This is all find and well, until you realize that your footnotes will be left sad and alone, abandoned for some cruel fate. In particular, it will break your document. - The better way is to define them all in-line; that will allow simple and easy re-factoring in a quite pleasant manner. - No comments in generated source code ever; barring a few special cases. - Always keep every kind of URL in a form that you may tell Ispell to ignore else you will get lose in the jungle of spell-checking and quit doing it. - For key, always use a finger that doesn't require a stretch or hand reposition. For example, I can use my "ring finger" to reach =-=, ~=~, and =DEL= so I should never stretch to do that with my "pinkie". - There are modes like ergoemacs [fn:6218cfd6: https://ergoemacs.github.io/] for doing this gradually * Confessions <2014-11-20 Thu T10:56:21> Looking back and this document, I am getting jealous of the clean and concise /final documents/ that people present on their ideal configurations. I wonder how they communicate the value of their approach, and do so without covering the whole history of their approach that demonstrates why their approach is ideal. Case in point, this document. I thought about reducing it to an /optimized version/ that was /lightweight/ and /fresh/. I had no reason to do this, of course, just the desire. Without thinking too deeply, I started looking at where I might /trim the fat/. Very, very quickly, I found that I could not make sense of any of the configuration *without* the history of why I made that configuration. Don't get me wrong, I can read English and read the APIs, so I know the functions and variables are. What I'm saying here is that, I don't remember why I did it /this/ way instead of the five other ways that would also have worked. Those things that I did not do, make what I do, valuable. The document is taking on a new form, as a friend, and record-keeper, and story-teller, and without those friends, this document becomes little more than a configuration file that can very easily be converted to HTML! This has and continues to be a fascinating experience! <2014-11-22 Sat> There are have actually been many versions of this system. I think that I touched on them up above well enough. More have come and gone, though. Perhaps they are not worth mentioning? What is worth mentioning is the motivation for those tangents (branches, at best). This idea, this desire, crept into my mind that I could "do it better". That is a fine idea, that is why we accomplish anything in life, because of the desire. The thing is that when I sought to satisfy that desire, it became clear that at best it was the wrong time and at worst there was no value to that desire. Now, still, it manifests in the form of "I should create a totally stable and /professional/ system!". To what end? Well, there is a real end, I never want the system to break after an update because I want to collaborate with others and I never want them to see breakage. So, that is a fine reason. The approach is where I got it wrong. Yet again, for at least the third time, I wanted to do a total "clean slate" re-write of this system. Generally, the rewrite starts out well and goes well because my mastery of the tools is better than before. The problem is that the tools just don't c-synchronize correctly together (non-technical term). They just don't gel together right and things don't wory right in very, very bizarre ways. Mostly it has to do with package loading. After a few hours, I blow away the changes and try again. The more I work, the more I feel like this system is an organic entity, the product of thousands, that has its own ebb and flow, and pushing it in one direction versus another yields often time pleasant and other time quite surprising results. I will focus on that which I am in control of, how *I* react, and move this forward a little more slowly. <2014-11-22 Sat> Oops I did it again, I made changes to the generated files, tested them, and didn't bring them back into the source file (this document). When I get tired, that happens. This goal of making things easier has been quite an adventure. It revealed a lot about myself and the tech. I am still human, and that is fine. None of the tools will think for you, so you definitely need to have a plan or no tool will ever succeed (more reports from captain obvious live on the 6 o'clock news!). The richness of the Emacs ecosystem is so vast and varied. There is so much, and so little, that you /need/ to know to be productive. It is kind of magical and mysterious, if you are open to seeing it at least. The more I think about it, I am just telling myself stories about reuse, here. There isn't really a need. No one else will re-use it. The value would be in the collaboration, not the tool. Why does the desire always precede the reason? <2015-01-03 Sat> Since the passage on the means of this system was capture… things have been content, and, quiet. I greatly, greatly look forward to enjoying collaborations with other people, expressing their selves, too, in the future. <2015-01-03 Sat> Added three new headings under one second-level heading. Before the addition: =Tangling complete after: 43.274528 seconds= After the addition: =Tangling complete after: 43.953333 seconds= # LocalWords: Savehist emacs fu API sudo MELPA purcell bbatsov ELPA LCO AHK # LocalWords: VM