{"id":24122199,"url":"https://github.com/tlinden/autoscratch","last_synced_at":"2026-01-25T08:31:58.470Z","repository":{"id":144612946,"uuid":"97320851","full_name":"TLINDEN/autoscratch","owner":"TLINDEN","description":"Automatically switch major mode from *scratch*","archived":false,"fork":false,"pushed_at":"2023-06-15T12:28:41.000Z","size":70,"stargazers_count":9,"open_issues_count":1,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-06-03T07:34:55.478Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://www.daemon.de/blog/2017/07/17/autoscratch-solve-scratch-buffer-problem/","language":"Emacs Lisp","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/TLINDEN.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-07-15T14:24:46.000Z","updated_at":"2025-05-01T11:24:43.000Z","dependencies_parsed_at":"2024-06-07T05:01:48.123Z","dependency_job_id":null,"html_url":"https://github.com/TLINDEN/autoscratch","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/TLINDEN/autoscratch","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TLINDEN%2Fautoscratch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TLINDEN%2Fautoscratch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TLINDEN%2Fautoscratch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TLINDEN%2Fautoscratch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TLINDEN","download_url":"https://codeload.github.com/TLINDEN/autoscratch/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TLINDEN%2Fautoscratch/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28749331,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-25T08:31:04.260Z","status":"ssl_error","status_checked_at":"2026-01-25T08:30:28.859Z","response_time":113,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-01-11T11:38:54.710Z","updated_at":"2026-01-25T08:31:58.465Z","avatar_url":"https://github.com/TLINDEN.png","language":"Emacs Lisp","funding_links":[],"categories":[],"sub_categories":[],"readme":"# autoscratch-mode - automatically switch scratch buffer mode\n\n*Author:* T.v.Dein \u003ctlinden AT cpan DOT org\u003e\u003cbr\u003e\n*URL:* [https://codeberg.org/scip/autoscratch](https://codeberg.org/scip/autoscratch)\u003cbr\u003e\n\n## Introduction\n\nThis simple  major mode can be  used as the initial  major mode for\nthe scratch buffer. It automatically switches to another major mode\nbased on regexes triggered by text input.\n\nIn   the   default  configuration   it   responds   to  the   first\nnon-whitespace  character  entered  into  the  scratch  buffer  and\nswitches   major   mode   based   on  this.    See   the   variable\n`autoscratch-triggers-alist` for the defaults.  For example, if you\nenter a paren, it will switch to `emacs-lisp-mode`.\n\n## History / Why\n\nI use emacs  for more than 20 years  now. I love it, I  am addicted, I\ncan't even do  anything productive without it. However,  there was one\nproblem left: the  *scratch* buffer. This is a  non-file buffer, which\nalways  exists always  in  emacs. By  default  it has  emacs-lisp-mode\nenabled and you can  use it to hack short elisp  sexps for testing. In\nfact I use it for exactly this purpose.\n\nBut sometimes I hate it as well! I get a phone call and need to take a\nnote quickly, *scratch*  is already open, so I use  this. But the mode\ndoesn't  really fit.  So  I switch  to text-mode  and  then enter  the\nnotes. I did it this way almost since day one of my emacs usage.\n\nA couple of  months ago I came  up with a \"solution\", I  just create a\n*text*  buffer  on  startup  with  text-mode  already  enabled  in  my\n.emacs. But I  still need to switch  to it everytime I  need it. Still\ntoo annoying!\n\nSo now,  here's my final solution,  which tries to fix  this mess once\nand for all: **autoscratch**.\n\nThis major  mode is really  simple. Basically  it consits of  an alist\nwith instructions on how to  automatically switch the *scratch** buffer\nmode. Enter an  \"(\" and it switches to emacs-lisp-mode,  enter \"*\" and\nit switches  to org-mode, enter  some letter  a-z, and it  switches to\ntext-mode. You get the idea.\n\nIt also  solves another problem I  (and many other users  according to\ngoogle)  have:  once  I  set   the  *scratch*  buffer  mode  to,  say,\n*text-mode* with some  text in there, I don't have  an elisp *scratch*\nbuffer left anymore. I'd need another  one, but how to create a second\n*scratch*  buffer?  Obviously  you'll   need  to  rename  the  current\ntext-mode buffer first  and then create a new empty  buffer. The [emacs\nwiki contains lots of suggestions](https://www.emacswiki.org/emacs/RecreateScratchBuffer)\nfor this kind of problem.\n\nNo more  of this! Autoscratch can  just \"fork\" the buffer,  if enabled\n(set autoscratch-fork-after-trigger to t which is the default). Here's\nhow it works: type a  \"(\" into the empty autoscratch-enabled *scratch*\nbuffer.  Autoscratch  renames  this  buffer  to  *emacs-lisp-scratch*,\nenables  emacs-lisp-mode and  creates a  new *scratch*  buffer in  the\nbackground. So, if  you need some *scratch* space, it'll  be there for\nyou waiting bravely for input.\n\n## Installation\n\nPut `autoscratch.el` into your load-path or use `package-install`\nto install it.\n\nIf you're using `use-package`, then add this:\n```elisp\n(use-package autoscratch\n  :ensure t\n  :config\n  (setq initial-major-mode 'autoscratch-mode))\n```\n\n## Configuration\n\nThe minimum configuration looks like this:\n\n        (require 'autoscratch)\n        (setq initial-major-mode 'autoscratch-mode)\n        (setq initial-scratch-message \"\")\n        (setq inhibit-startup-screen t)\n\nYou     may,     however,     configure    the     trigger     list\n`autoscratch-triggers-alist` according  to your  preferences.  This\nlist consists  of cons cells, where  the `car` is a  regexp and the\n`cdr` an emacs lisp form (e.g. a  lambda or defun).  If you want to\nuse regexps which  match more than one character, then  you need to\nset `autoscratch-trigger-on-first-char`  to `nil` and  possibly tune\n`autoscratch-trigger-after` accordingly.\n\nIf   no  regexp   matches  and/or   `autoscratch-trigger-after`  is\nexceeded,  then  the  `autoscratch-default-trigger`  form  will  be\nexecuted, which  by default is  `fundamental-mode`, but you  can of\ncourse change this.\n\n### This is the default trigger list:\n\n```lisp\n((\"[(;]\"         . (emacs-lisp-mode))\n    (\"#\"            . (autoscratch-select\n                       '((\"perl\"   . (cperl-mode))\n                         (\"ruby\"   . (ruby-mode))\n                         (\"python\" . (python-mode))\n                         (\"conf\"   . (conf-unix-mode))\n                         (\"shell\"  . (shell-script-mode)))))\n    (\"[-a-zA-Z0-9]\" . (text-mode))\n    (\"/\"            . (c-mode))\n    (\"*\"            . (progn (insert \" \") (org-mode)))\n    (\".\"            . (fundamental-mode)))\n```\n\nPlease note  the trigger of  the `#` character: an  interactive prompt\nwill ask you which mode to select.\n\nAutoscratch can  also be  configured to  rename the  current buffer\nafter  it  switched mode  based  on  a  trigger  and create  a  new\n`autoscratch-buffer`  in the  background. In  order to  enable this\nfeature, set `autoscratch-fork-after-trigger` to t.\n\nThis is my own config:\n```lisp\n(use-package autoscratch\n  :ensure t\n  :config\n  (setq initial-major-mode 'autoscratch-mode)\n  (add-hook 'autoscratch-mode-hook '(lambda ()\n     (setq autoscratch-triggers-alist\n           '((\"[(;]\"         . (progn\n                                 (call-interactively 'emacs-lisp-mode)\n                                 (call-interactively 'enable-paredit-mode)\n                                 (call-interactively 'electric-pair-mode)))\n             (\"#\"            . (progn\n                                 (call-interactively 'config-general-mode)\n                                 (electric-indent-local-mode t)))\n             (\"[-a-zA-Z0-9]\" . (text-mode))\n             (\"/\"            . (c-mode))\n             (\"*\"            . (progn (insert \" \") (org-mode)))\n             (\".\"            . (fundamental-mode)))\n           autoscratch-trigger-on-first-char t\n           autoscratch-reset-default-directory t)\n     (electric-indent-local-mode nil)))\n  (defalias 'scratch 'autoscratch-buffer))\n```\n\nI'd also recommend to use [persistent-scratch](https://github.com/Fanael/persistent-scratch)\nin combination with autoscratch, here's my config for this:\n\n```listp\n(defun tvd-autoscratch-p ()\n  \"Return non-nil if the current buffer is a scratch buffer\"\n  (string-match \"scratch*\" (buffer-name)))\n\n(use-package persistent-scratch\n             :config\n             (setq persistent-scratch-save-file (expand-file-name \"scratches.el\" user-emacs-directory))\n             (persistent-scratch-setup-default)\n\n             (setq persistent-scratch-scratch-buffer-p-function 'tvd-autoscratch-p))\n```\n\nIf you're  using evil  mode than,  you might  better setup  an initial\nstate for autoscratch (it doesn't make much sense otherwise):\n```\n(evil-set-initial-state 'autoscratch-mode 'insert)\n```\n\n## Configuration Reference\n\n| Variable                              | Setting                                                             | Default Value                  |\n|---------------------------------------|---------------------------------------------------------------------|--------------------------------|\n| `autoscratch-triggers-alist`          | List of single char commands with their triggering lisp             | see above default trigger list |\n| `autoscratch-trigger-on-first-char`   | Trigger after the first character has been entered, no matter what. | `t`                            |\n| `autoscratch-default-trigger`         | Default form to execute when nothing else matches.                  | `'(fundamental-mode)`          |\n| `autoscratch-fork-after-trigger`      | Create a new autoscratch buffer after the trigger fired.            | `t`                            |\n| `autoscratch-trigger-after`           | Max chars to be entered to force trigger the default form.          | `5`                            |\n| `autoscratch-reset-default-directory` | Reset default directory when a new scratch buffer is created.       | `nil`                          |\n\n| Hook                       | Purpose                                               |\n|----------------------------|-------------------------------------------------------|\n| `autoscratch-trigger-hook` | Hooks called after executing a matching trigger form. |\n| `autoscratch-rename-hook`  | Hooks called after renaming the current buffer.       |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftlinden%2Fautoscratch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftlinden%2Fautoscratch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftlinden%2Fautoscratch/lists"}