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