Files
autoscratch/README.md

186 lines
8.4 KiB
Markdown
Raw Normal View History

2017-07-19 11:26:06 +02:00
[![Build Status](https://travis-ci.org/TLINDEN/autoscratch.svg?branch=master)](https://travis-ci.org/TLINDEN/autoscratch)
2017-07-15 16:29:19 +02:00
# autoscratch-mode - automatically switch scratch buffer mode
*Author:* T.v.Dein <tlinden AT cpan DOT org><br>
2017-07-15 16:30:20 +02:00
*URL:* [https://github.com/tlinden/autoscratch](https://github.com/tlinden/autoscratch)<br>
2017-07-15 16:29:19 +02:00
## Introduction
This simple major mode can be used as the initial major mode for
the scratch buffer. It automatically switches to another major mode
based on regexes triggered by text input.
In the default configuration it responds to the first
non-whitespace character entered into the scratch buffer and
switches major mode based on this. See the variable
`autoscratch-triggers-alist` for the defaults. For example, if you
enter a paren, it will switch to `emacs-lisp-mode`.
2023-06-01 18:49:48 +02:00
## History / Why
I use emacs for more than 20 years now. I love it, I am addicted, I
can't even do anything productive without it. However, there was one
problem left: the *scratch* buffer. This is a non-file buffer, which
always exists always in emacs. By default it has emacs-lisp-mode
enabled and you can use it to hack short elisp sexps for testing. In
fact I use it for exactly this purpose.
But sometimes I hate it as well! I get a phone call and need to take a
note quickly, *scratch* is already open, so I use this. But the mode
doesn't really fit. So I switch to text-mode and then enter the
notes. I did it this way almost since day one of my emacs usage.
A couple of months ago I came up with a "solution", I just create a
*text* buffer on startup with text-mode already enabled in my
.emacs. But I still need to switch to it everytime I need it. Still
too annoying!
So now, here's my final solution, which tries to fix this mess once
and for all: **autoscratch**.
This major mode is really simple. Basically it consits of an alist
with instructions on how to automatically switch the *scratch** buffer
mode. Enter an "(" and it switches to emacs-lisp-mode, enter "*" and
it switches to org-mode, enter some letter a-z, and it switches to
text-mode. You get the idea.
It also solves another problem I (and many other users according to
google) have: once I set the *scratch* buffer mode to, say,
*text-mode* with some text in there, I don't have an elisp *scratch*
buffer left anymore. I'd need another one, but how to create a second
*scratch* buffer? Obviously you'll need to rename the current
2023-06-01 18:51:47 +02:00
text-mode buffer first and then create a new empty buffer. The [emacs
wiki contains lots of suggestions](https://www.emacswiki.org/emacs/RecreateScratchBuffer)
for this kind of problem.
2023-06-01 18:49:48 +02:00
No more of this! Autoscratch can just "fork" the buffer, if enabled
(set autoscratch-fork-after-trigger to t which is the default). Here's
how it works: type a "(" into the empty autoscratch-enabled *scratch*
buffer. Autoscratch renames this buffer to *emacs-lisp-scratch*,
enables emacs-lisp-mode and creates a new *scratch* buffer in the
background. So, if you need some *scratch* space, it'll be there for
you waiting bravely for input.
## Installation
2023-06-01 19:34:34 +02:00
Put `autoscratch.el` into your load-path or use `package-install`
2023-06-01 18:49:48 +02:00
to install it.
If you're using `use-package`, then add this:
```elisp
(use-package autoscratch
:ensure t
:config
(setq initial-major-mode 'autoscratch-mode))
```
2017-07-15 16:29:19 +02:00
## Configuration
The minimum configuration looks like this:
2023-06-01 19:34:34 +02:00
(require 'autoscratch)
2017-07-15 16:29:19 +02:00
(setq initial-major-mode 'autoscratch-mode)
2017-07-17 17:17:43 +02:00
(setq initial-scratch-message "")
(setq inhibit-startup-screen t)
2017-07-15 16:29:19 +02:00
You may, however, configure the trigger list
`autoscratch-triggers-alist` according to your preferences. This
list consists of cons cells, where the `car` is a regexp and the
`cdr` an emacs lisp form (e.g. a lambda or defun). If you want to
use regexps which match more than one character, then you need to
2017-07-15 21:45:04 +02:00
set `autoscratch-trigger-on-first-char` to `nil` and possibly tune
2017-07-15 16:29:19 +02:00
`autoscratch-trigger-after` accordingly.
If no regexp matches and/or `autoscratch-trigger-after` is
exceeded, then the `autoscratch-default-trigger` form will be
executed, which by default is `fundamental-mode`, but you can of
course change this.
2023-06-13 14:51:33 +02:00
### This is the default trigger list:
2023-06-01 18:49:48 +02:00
```lisp
(("[(;]" . (emacs-lisp-mode))
("#" . (autoscratch-select
'(("perl" . (cperl-mode))
("ruby" . (ruby-mode))
("python" . (python-mode))
("conf" . (conf-unix-mode))
("shell" . (shell-script-mode)))))
("[-a-zA-Z0-9]" . (text-mode))
("/" . (c-mode))
("*" . (progn (insert " ") (org-mode)))
("." . (fundamental-mode)))
```
Please note the trigger of the `#` character: an interactive prompt
will ask you which mode to select.
2017-07-15 16:29:19 +02:00
Autoscratch can also be configured to rename the current buffer
after it switched mode based on a trigger and create a new
`autoscratch-buffer` in the background. In order to enable this
feature, set `autoscratch-fork-after-trigger` to t.
2023-06-01 18:49:48 +02:00
This is my own config:
```lisp
2023-06-01 19:34:34 +02:00
(use-package autoscratch
2023-06-01 18:49:48 +02:00
:ensure t
:config
(setq initial-major-mode 'autoscratch-mode)
(add-hook 'autoscratch-mode-hook '(lambda ()
(setq autoscratch-triggers-alist
'(("[(;]" . (progn
(call-interactively 'emacs-lisp-mode)
(call-interactively 'enable-paredit-mode)
(call-interactively 'electric-pair-mode)))
("#" . (progn
(call-interactively 'config-general-mode)
(electric-indent-local-mode t)))
("[-a-zA-Z0-9]" . (text-mode))
("/" . (c-mode))
("*" . (progn (insert " ") (org-mode)))
("." . (fundamental-mode)))
autoscratch-trigger-on-first-char t
autoscratch-reset-default-directory t)
(electric-indent-local-mode nil)))
(defalias 'scratch 'autoscratch-buffer))
```
I'd also recommend to use [persistent-scratch](https://github.com/Fanael/persistent-scratch)
in combination with autoscratch, here's my config for this:
```listp
(defun tvd-autoscratch-p ()
"Return non-nil if the current buffer is a scratch buffer"
(string-match "scratch*" (buffer-name)))
(use-package persistent-scratch
:config
(setq persistent-scratch-save-file (expand-file-name "scratches.el" user-emacs-directory))
(persistent-scratch-setup-default)
(setq persistent-scratch-scratch-buffer-p-function 'tvd-autoscratch-p))
```
If you're using evil mode than, you might better setup an initial
state for autoscratch (it doesn't make much sense otherwise):
```
(evil-set-initial-state 'autoscratch-mode 'insert)
```
2023-06-13 14:51:33 +02:00
## Configuration Reference
| Variable | Setting | Default Value |
|---------------------------------------|---------------------------------------------------------------------|--------------------------------|
| `autoscratch-triggers-alist` | List of single char commands with their triggering lisp | see above default trigger list |
| `autoscratch-trigger-on-first-char` | Trigger after the first character has been entered, no matter what. | `t` |
| `autoscratch-default-trigger` | Default form to execute when nothing else matches. | `'(fundamental-mode)` |
| `autoscratch-fork-after-trigger` | Create a new autoscratch buffer after the trigger fired. | `t` |
| `autoscratch-trigger-after` | Max chars to be entered to force trigger the default form. | `5` |
| `autoscratch-reset-default-directory` | Reset default directory when a new scratch buffer is created. | `nil` |
| Hook | Purpose |
|----------------------------|-------------------------------------------------------|
| `autoscratch-trigger-hook` | Hooks called after executing a matching trigger form. |
| `autoscratch-rename-hook` | Hooks called after renaming the current buffer. |