Skip to content

BrunoBonacci/lambdamacs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

(λmacs)

(λmacs) is Emacs for Clojure development on macOS X.

./assets/lambdamacs_600.png

Intro

Motivation

For a number of years I’ve been using Emacs as my primary/only IDE. I used a number of ”distributions” readily available on internet such as emacs-live and Prelude of which I made my own extension Preludex, and I watched the birth of Spacemacs and the new challenger doom-emacs.

Over time each of these distributions grew larger and larger and it became hard to keep the configuration up-to-date but still minimal (just what you need).

So I decided to build my own out of the best pieces of all of them.

If you are new to Emacs, it is probably best if you start with one of the more popular distributions so that you get enough community support. If only you need is to develop Clojure, and have enough tooling support feel free to use my configuration.

Installation

Alternatively you can install it via:

sudo mkdir /usr/local/Frameworks
sudo chown $(whoami):admin /usr/local/Frameworks
brew tap d12frosted/emacs-plus
brew install emacs-plus@29 --with-no-frame-refocus --with-xwidgets --with-imagemagick --with-native-comp --with-elrumo2-icon

You can check github://d12frosted/homebrew-emacs-plus what each option does.

NOTE: you can choose your icon here and replace the last argument with the one you want

  • Backup your previous installation:
mv ~/.emacs.d ~/.emacs.d-backup
  • Clone (λmacs)
git clone https://github.com/BrunoBonacci/lambdamacs.git ~/.emacs.d
  • Install platform tools

Some platform tools are used to enhance the user experience and to support some features.

brew install the_silver_searcher aspell fd
  • That’s all, start hacking!

If you want you can customize your configuration (see next section).

Configuration

There are a number of configurable options to setup (λmacs) just right for your environment.

To change the configuration file edit config/user-config.el.

  • First configure your name and email:
;; add your name and email address
(setq user-full-name    "Firstname Lastname"
      user-mail-address "your-email@email.org")
  • Install a nice looking font and pick a size:

Here some suggestions:

(setq lambdamacs/default-font "Roboto Mono Thin for Powerline")
(setq lambdamacs/default-font-size 150)
  • Select your favorite theme

There are a number a themes already installed see the full list and see theme screenshots. I’d recommend to pick your favorite as default and use a light theme as alternative. It can be useful sometimes to switch to the alternative for example if you make a presentation. Light themes work better with projectors.

(setq lambdamacs/default-theme 'doom-moonlight)
(setq lambdamacs/alternative-theme 'doom-one-light)

You can switch between themes by typing M-x lambdamacs/switch-theme-to-alternative and switch back to the default theme with M-x lambdamacs/switch-theme-to-default

Structure

(λmacs) has the following project structure:

.emacs.d
├── init.el    - main emacs init file
├── config/    - user configuration and other settings
├── modules/   - packages which are not available in MELPA
├── src/       - packages installation and configuration
├── assets/    - Assets for this project (images, css, etc)
├── yas/       - Custom Yasnippets
└── .save/     - Locally saved items (history, items etc.)

Packages installed

PackagePurpose
avyJump where you want (like ace-jump)
bmBookmarks management
bookmarksCode bookmarks
browse-at-remoteBrowse selected files or lines on Github (and other repos)
carbon-now-shGenerate images from code snippets, useful for presentations.
ciderCIDER the best IDE for Clojude development
clj-refactorCider companion for refactoring
command-logDisplays a buffer with the keys and commands you type
doom-modelinecool minimalistic modeline
doom-themea collection of well curated themes
flycheckRun checks on the fly
flyspellSpell checking
forgeMagit extension for Pull Requests and Issues
google-thisQuickly Google something at point
magitGit controls
markdownMarkdown mode support with TOC and Live preview (via flymd)
multiple-cursorsMultiple cursors for editing
outline-presentationUse org-mode to make a presentation
paradoxA package manager which makes very easy to update your installation
pareditCan’t develop Clojure without structural editing
password-generatorGenerate strong random passwords
prodigyLocal process management
projectileUseful functions for working with projecs
restclientTurn simple text buffer into HTTP REST calls
sticky-windowsStick windows in place (no auto close)
switch-javaEnables to select the JVM version while inside emacs
undo-treePowerful multi-state undo
wgrepEditable search buffers
witespaceTo clean trailing whitespaces in the code
wsdWebSequenceDiagrams
yas-snippetCode snippets
  • TODO:
  • [ ] wsd
  • [ ] workgroups / persp-mode / toggle-zoom ??
  • [ ] code rtf pygments
  • [ ] repl image hack

Keybindings

Here is the list of keybindings which are added by this configuration. All standard keybindings are valid, plus the default keybindings of the pacakge installed.

Here is how to read the keybindings:

  • C-x - means Ctrl + x
  • C-x 1 - means Ctrl + x followed by 1
  • M-x - means Meta + x or Alt + x or Option + x
  • s-x - means Super + x or Command ⌘ + x
  • SPC - is space bar
  • RET - is reutrn key

Here the keybindings added/defined by (λmacs):

Mode or groupKeyActionModule
clojure-modeM-SPCRemoves all the blanks between two forms except one(λmacs)
clojure-modes-bAdds a nice comment box with current line.(λmacs)
clojure-modeC-c C-rPrefix for Clojure refactoring functionsclj-refactor
cider-modeC-c C-{Decompiles the previous form (into Java code)clj-decompiler
editorM-yBrowse the content of the kill-ringbrowse-kill-ring
editorC-aSmart beginning of the line (non blank)crux
editor⌘-cCopy selected region (like macOS - more natural)cua-mode
editor⌘-vPaste selected region (like macOS - more natural)cua-mode
editorC-RETToggle rectangular selectioncua-mode
editorC-=Expands the selection to the larger surrounding form.expand-region
editorM-/ or s-/Hippie expansion (completion)hippie
editorC->multi-cursor mark next like thismultiple-cursors
editorC-<multi-cursor mark previous like thismultiple-cursors
editorC-c C-<multi-cursor mark all like thismultiple-cursors
editorC-M-s-. C-M-s-.Adds a cursor on each line of a multi-line selectionmultiple-cursors
editorC-x jJump to section in buffer (depends on current mode)counsel
editors-j + charJumps to the word starting with the given charavy
editors-. + charJumps to the location selected with the given charavy
editors-w + charJumps to the window selected with the given charavy
editorC-c C-wOpens the selected file in Githubbrowse-at-remote
editorC-c C-S-wCopy the link of the selected file in Github in kill-ringbrowse-at-remote
editor⌘-←Restore previous window layoutwinner
editor⌘-→Redo previous window layoutwinner
editorM-s-cCalls carbon-now-sh and generate an image with your codecarbon-now-sh
bookmarkss-1Toggle bookmarkbm
bookmarkss-2Cycle previous bookmarksbm
bookmarkss-3Cycle next bookmarksbm
bookmarkss-5Create bookmarks by regexbm
bookmarkss-0Clear all bookmarks in this bufferbm
bookmarkss-S-0Clear all bookmarks in all buffersbm
files/buffersC-x C-/Open dired explorer for the current file.(λmacs)
files/buffersC-c tOpen a shell terminalcrux
files/bufferss-rOpen a recently opened filecrux
files/buffersC-u C-x 0Closes a locked window (via C-x 9)sticky-windows
files/buffersM-s- + ← → ↑ ↓Move between windows (same keys as iTerm)(λmacs)
windowsC-S- + ← → ↑ ↓Resize current window using keybindingswindsize
processesC-x pOpen Prodigy’s status buffer (start/stop processes)prodigy
projectC-x gOpen Magit statusmagit
projectC-x M-gMinibuffer popup with Magit dispatch functionsmagit
projectC-x g + C-oOpen the current project in Githubmagit
projectC-c p or s-pProjectile’s prefixprojectile
projectC-x 9Locks the window in place so that it can’t be closed.sticky-windows
alls-gGoogle word or region at pointgoogle-this

Features

Here some features implemented/available in (λmacs)

Switch Java version

(λmacs) focus is on Clojure development. Clojure is a JVM hosted language. JVM release process has been traditionally quite slow, but in the recent years Oracle and OpenJDK have speed up the release process to roughly every 6 months.

For this reason it is common to having the need to use/try different version of the underlying JVM while working on a Clojure project.

Emacs doesn’t have a facility to do this and, to my knowledge, there is package that handles this. For this reason I wrote a module that offers this possibility and described the solution in this blog post: Switching between multiple Java JDK versions in Emacs.

You can read more about the solution in the blog post but here I will only describe how it works.

Firstly you need to tell (λmacs) where your JDKs are installed. Typically on a macOS the default location is: /Library/Java/JavaVirtualMachines.

If this is the location where are your JDK versions are installed then you don’t need to change the configuration, otherwise select the appropriate folder in the config/user-config.el file.

;; base directory where all the JDK versions are installed
;; use `M-x switch-java' to select the JVM to use
(setq JAVA_BASE "/Library/Java/JavaVirtualMachines")

Once you set the base directory where all your JDKs are installed and evaluated the form, to select a JVM to use you can just run: M-x switch-java which will show the list of available JVMs. Once you select one JDK, it will update the $JVM_HOME environment variable and use it whenever you start a new REPL or java application.

Here other commands you can run:

  • M-x switch-java select a JDK from a list of available ones
  • M-x switch-java-default will select the system default JDK (the one in use prior any selection)
  • M-x switch-java-which-version? displays the JDK currently in use.

You can see a usage demo here:

http://blog.brunobonacci.com/images/switch-java.gif

Custom yasnippets

yasnippets is a templating minor-mode with allows to define code templates and complete them with a few keystrokes. Think about the repetitve structures in your code. Check out this demo on Youtube. It works across languages and there are plenty of predefine templates Here the is a list of all most of the boundled snippets.

However if you want to define your own snippets you can drop them in ~/.emacs.d/yas folder divided by major-mode. If you are unfamiliar with the templating language used by yasnippet you can check the official online documentation.

Restclient

If you do RESTful services development restclient is going to be your best companion.

restclient turns normal text buffers into executable HTTP requests ideal to tests your webservices.

For example, create an empty buffer, activate the move via M-x restclient-mode then write your HTTP requests like:

#
# retrieve your current IP address
#
GET http://ifconfig.co/ip


#
# retrieve the geolocation city info
#
GET http://ifconfig.co/city
Accept: text/plain


#
# retrieve all as json
#
GET http://ifconfig.co/json
Content-Type: application/json

After each request try to press C-c C-v to execute the request and see the response.

All *.rest files are in restclient-mode by default.

Here a list of all the keybindings for this mode:

  • C-c C-c : runs the query under the cursor, tries to pretty-print the response (if possible)
  • C-c C-r : same, but doesn’t do anything with the response, just shows the buffer
  • C-c C-v : same as C-c C-c, but doesn’t switch focus to other window
  • C-c C-p : jump to the previous query
  • C-c C-n : jump to the next query
  • C-c C-. : mark the query under the cursor
  • C-c C-u : copy query under the cursor as a curl command
  • C-c C-g : start a [helm](https://emacs-helm.github.io/helm/) session with sources for variables and requests (if helm is available, of course)
  • C-c n n : narrow to region of current request (including headers)
  • TAB : hide/show current request body, only if
  • C-c C-a : show all collapsed regions
  • C-c C-i : show information on resclient variables at point

cljfmt auto-format

The way Cider formats the code isn’t particularly nice. To format the code properly you need to have a repl running and the code needs to be loaded. Because of this the formatting changes depending on which state your IDE is. I think it is a bad idea. I rather have a less appealing formatting, but which can be done without having to load/compile the code.

(λmacs) performs a reformatting of the code on save with a definition which doesn’t take into account which particular form you are in. However, there are times this is not convenient, like when working on someone else code. To disable the code-reformat set the variable lambdamacs/cljfmt-reformat-on-save to nil in the configuration.

(setq lambdamacs/cljfmt-reformat-on-save nil)

You can toggle the value with M-x cljfmt-toggle-reformat.

Get involved

Contribution

This is my personal setup, I don’t mind you using it and I’d appreciate feedbacks and suggestions on how to improve it! Issue a PR, and if it works for me, I’ll merge it!

References

The code in this repo has is the sum of my personal experience and the following references:

Thank you to all of you!

License

Copyright © 2020 Bruno Bonacci and contributors. Distributed under the GNU General Public License, version 3.