{"id":23435519,"url":"https://github.com/customcommander/dotfiles","last_synced_at":"2026-02-14T23:32:32.522Z","repository":{"id":167135916,"uuid":"615702809","full_name":"customcommander/dotfiles","owner":"customcommander","description":null,"archived":false,"fork":false,"pushed_at":"2025-10-04T07:15:40.000Z","size":118,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-06T22:34:35.475Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Emacs Lisp","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/customcommander.png","metadata":{"files":{"readme":"README.org","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-03-18T12:38:50.000Z","updated_at":"2025-10-04T07:15:44.000Z","dependencies_parsed_at":null,"dependency_job_id":"4ccc6ec7-479c-4d0f-83fb-ed52f067b40d","html_url":"https://github.com/customcommander/dotfiles","commit_stats":null,"previous_names":["customcommander/dotfiles"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/customcommander/dotfiles","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/customcommander%2Fdotfiles","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/customcommander%2Fdotfiles/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/customcommander%2Fdotfiles/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/customcommander%2Fdotfiles/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/customcommander","download_url":"https://codeload.github.com/customcommander/dotfiles/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/customcommander%2Fdotfiles/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29460717,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-14T22:42:09.113Z","status":"ssl_error","status_checked_at":"2026-02-14T22:42:05.053Z","response_time":53,"last_error":"SSL_read: 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":"2024-12-23T12:51:44.978Z","updated_at":"2026-02-14T23:32:32.503Z","avatar_url":"https://github.com/customcommander.png","language":"Emacs Lisp","funding_links":[],"categories":[],"sub_categories":[],"readme":"* My Dotfiles\n\n** Development\n\nI use Emacs and its literate programming features.\n\nThe content of both the =Makefile= and the =files= directory\nis generated out of this org file, so do not edit these directly\nbut work on this document instead!\n\nThen:\n\n1. Run =C-c C-v t=\n2. Commit all the changes\n3. Run =make=\n\n** Install\n\n1. Clone this repository (or pull the latest changes)\n2. Run =make=\n\nThese are the files that will be copied over your home directory\n\n#+begin_src makefile :tangle Makefile :mkdirp yes\ninstall: $(HOME)/.gitconfig \\\n         $(HOME)/.gitconfig-local \\\n         $(HOME)/.gitignore \\\n         $(HOME)/.emacs.d/init.el\n#+end_src\n\n** My Setup\n\n*** Manual Install\n\n#+begin_src shell\nbrew install clojure-lsp/brew/clojure-lsp-native\n#+end_src\n\n*** Git\n\nMy global Git configuration file will be installed in my home directory:\n\n#+begin_src makefile :tangle Makefile :mkdirp yes\n$(HOME)/.gitconfig: files/.gitconfig\n\tcp -f $^ $@\n#+end_src\n\nIt will make provision for local additions that\ncan't be checked in for whatever reason (e.g. work stuff).\n\n#+begin_src text :tangle files/.gitconfig :mkdirp yes\n  [include]\n          path = ~/.gitconfig-local\n#+end_src\n\nThat file also lives in my home directory:\n\n#+begin_src makefile :tangle Makefile\n$(HOME)/.gitconfig-local:; touch $(HOME)/.gitconfig-local\n#+end_src\n\nThese are the things I always want Git to ignore:\n\n#+begin_src text :tangle files/.gitignore :mkdirp yes\n,*~\n.DS_Store\n.\\#*\n.clj-kondo\n.cljs_node_repl\n.cpcache\n.hgignore\n.lsp\n.nrepl-port\n\\#*\\#\ndist\nnode_modules\nout\nresources\ntarget\n#+end_src\n\nThese patterns live in a file in my home directory:\n\n#+begin_src makefile :tangle Makefile\n$(HOME)/.gitignore: files/.gitignore\n\tcp -f $^ $@\n#+end_src\n\nAnd that file is referenced in my global Git configuration file:\n\n#+begin_src text :tangle files/.gitconfig :mkdirp yes\n  [core]\n          excludesFile = ~/.gitignore\n#+end_src\n\n*** Emacs\n\nOpen Emacs maximised:\n\n#+begin_src emacs-lisp :tangle files/init.el\n  (add-to-list 'initial-frame-alist '(fullscreen . maximized))\n#+end_src\n\n/Remember that what we usually refer to as a window is called a frame in Emacs parlance./\n\nI don't find both Emacs toolbar \u0026 scrollbar very useful so I disable them:\n\n#+begin_src emacs-lisp :tangle files/init.el\n  (tool-bar-mode -1)\n  (scroll-bar-mode -1)\n#+end_src\n\nDisable default left and right margins:\n\n#+begin_src emacs-lisp :tangle files/init.el\n  (set-fringe-mode 0)\n#+end_src\n\nI always want to see line numbers so I enable that feature globally:\n\n#+begin_src emacs-lisp :tangle files/init.el\n  (global-display-line-numbers-mode t)\n#+end_src\n\nI need this as other I cannot type that character :)\n\n#+begin_src emacs-lisp :tangle files/init.el\n  (global-set-key (kbd \"M-3\") (lambda ()\n                                (interactive)\n                                (insert \"#\")))\n#+end_src\n\nThis seems to be frowned upon but I find using =Shift= and the arrow keys\nreally handy to navigate the windows:\n\n#+begin_src emacs-lisp :tangle files/init.el\n  (windmove-default-keybindings)\n#+end_src\n\nThis allows a \"circular\" navigation e.g. if you reach the last window\nthen =Shift-\u003cArrow Left\u003e= get you back to the first window.\n\n#+begin_src emacs-lisp :tangle files/init.el\n  (setq windmove-wrap-around t)\n#+end_src\n\n#+begin_src emacs-lisp :tangle files/init.el\n(setq treesit-language-source-alist\n      '((tsx \"https://github.com/tree-sitter/tree-sitter-typescript\" \"master\" \"tsx/src\")\n        (typescript \"https://github.com/tree-sitter/tree-sitter-typescript\" \"master\" \"typescript/src\")))\n\n(mapc #'treesit-install-language-grammar (mapcar #'car treesit-language-source-alist))\n#+end_src\n\nIndentation\n\n#+begin_src emacs-lisp :tangle files/init.el\n  (electric-indent-mode -1)\n  (setq-default indent-tabs-mode nil)\n  (setq-default tab-width 2)\n  (setq-default js-indent-level 2)\n#+end_src\n\nI need this to avoid choking lsp-mode:\nhttps://emacs-lsp.github.io/lsp-mode/page/performance/\n\n#+begin_src emacs-lisp :tangle files/init.el\n  (setq read-process-output-max (* 1024 1024)) ;; 1mb\n  (setq gc-cons-threshold 100000000)\n#+end_src\n\nUse =ibuffer= instead of =list-buffers= on =C-x C-b=\n\n#+begin_src emacs-lisp :tangle files/init.el\n(global-set-key (kbd \"C-x C-b\") 'ibuffer)\n#+end_src\n\n**** Packages\n\nI use [[https://github.com/radian-software/straight.el][straight.el]] as my package manager.\n\nThis is what is needed to bootstrap it:\n\n#+begin_src emacs-lisp :tangle files/init.el\n  (defvar bootstrap-version)\n\n  (let ((bootstrap-file\n         (expand-file-name \"straight/repos/straight.el/bootstrap.el\" user-emacs-directory))\n        (bootstrap-version 6))\n    (unless (file-exists-p bootstrap-file)\n      (with-current-buffer\n          (url-retrieve-synchronously\n           \"https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el\"\n           'silent 'inhibit-cookies)\n        (goto-char (point-max))\n        (eval-print-last-sexp)))\n    (load bootstrap-file nil 'nomessage))\n\n  ;; tell `use-package` to use `straight.el` as the package manager\n  (setq straight-use-package-by-default t)\n\n  (straight-use-package 'use-package)\n#+end_src\n\n**** Fira Code\n\nFirst, make sure [[https://github.com/tonsky/FiraCode][Fira Code]] is installed!\n\n#+begin_src emacs-lisp :tangle files/init.el\n(set-frame-font \"Fira Code:size=14\")\n\n(use-package ligature\n  :init\n  ;; Enable the www ligature in every possible major mode\n  (ligature-set-ligatures 't '(\"www\"))\n\n  ;; Enable ligatures in programming modes                                                           \n  (ligature-set-ligatures 'prog-mode '(\"www\" \"**\" \"***\" \"**/\" \"*\u003e\" \"*/\" \"\\\\\\\\\" \"\\\\\\\\\\\\\" \"{-\" \"::\"\n                                       \":::\" \":=\" \"!!\" \"!=\" \"!==\" \"-}\" \"----\" \"--\u003e\" \"-\u003e\" \"-\u003e\u003e\"\n                                       \"-\u003c\" \"-\u003c\u003c\" \"-~\" \"#{\" \"#[\" \"##\" \"###\" \"####\" \"#(\" \"#?\" \"#_\"\n                                       \"#_(\" \".-\" \".=\" \"..\" \"..\u003c\" \"...\" \"?=\" \"??\" \";;\" \"/*\" \"/**\"\n                                       \"/=\" \"/==\" \"/\u003e\" \"//\" \"///\" \"\u0026\u0026\" \"||\" \"||=\" \"|=\" \"|\u003e\" \"^=\" \"$\u003e\"\n                                       \"++\" \"+++\" \"+\u003e\" \"=:=\" \"==\" \"===\" \"==\u003e\" \"=\u003e\" \"=\u003e\u003e\" \"\u003c=\"\n                                       \"=\u003c\u003c\" \"=/=\" \"\u003e-\" \"\u003e=\" \"\u003e=\u003e\" \"\u003e\u003e\" \"\u003e\u003e-\" \"\u003e\u003e=\" \"\u003e\u003e\u003e\" \"\u003c*\"\n                                       \"\u003c*\u003e\" \"\u003c|\" \"\u003c|\u003e\" \"\u003c$\" \"\u003c$\u003e\" \"\u003c!--\" \"\u003c-\" \"\u003c--\" \"\u003c-\u003e\" \"\u003c+\"\n                                       \"\u003c+\u003e\" \"\u003c=\" \"\u003c==\" \"\u003c=\u003e\" \"\u003c=\u003c\" \"\u003c\u003e\" \"\u003c\u003c\" \"\u003c\u003c-\" \"\u003c\u003c=\" \"\u003c\u003c\u003c\"\n                                       \"\u003c~\" \"\u003c~~\" \"\u003c/\" \"\u003c/\u003e\" \"~@\" \"~-\" \"~\u003e\" \"~~\" \"~~\u003e\" \"%%\"))\n  \n  (global-ligature-mode 't)\n)\n#+end_src\n\n***** Completion\n\n#+begin_src emacs-lisp :tangle files/init.el\n\n(use-package vertico\n  :ensure t\n  :init\n  (vertico-mode t)\n  :custom\n  (vertico-cycle t) ; goes back to the top when reaching the end of minibuffer\n  )\n\n#+end_src\n\n#+begin_src emacs-lisp :tangle files/init.el\n\n(use-package marginalia\n  :ensure t\n  :init\n  (marginalia-mode t))\n\n#+end_src\n\nProvide fuzzy search:\n\n#+begin_src emacs-lisp :tangle files/init.el\n\n(use-package orderless\n  :ensure t\n  :config\n  (setq completion-styles '(orderless basic)))\n\n#+end_src\n\n***** consult\n\n=consult-xref= is nice alternative to a plain =*xref*= buffer, especially\nwhen combined with =lsp-mode=!\n\n#+begin_src emacs-lisp :tangle files/init.el\n(use-package consult\n  :init\n  (setq xref-show-xrefs-function #'consult-xref\n        xref-show-definitions-function #'consult-xref)\n  :bind ((\"C-x b\" . consult-buffer)\n         (\"C-s\" . consult-line)))\n\n#+end_src\n\n#+begin_src emacs-lisp :tangle files/init.el\n\n(use-package which-key\n  :init\n  (which-key-mode t))\n\n#+end_src\n\n\n***** Theme\n\nInstall and use [[https://github.com/protesilaos/ef-themes][ef-themes]] from Prot.\n\n#+begin_src emacs-lisp :tangle files/init.el\n  (use-package ef-themes\n    :init (ef-themes-select 'ef-maris-dark))\n#+end_src\n\n#+begin_src emacs-lisp :tangle files/init.el\n(use-package lsp-mode\n  :commands lsp\n  :init\n  (setq lsp-keymap-prefix \"C-c l\")\n  :hook ((typescript-ts-mode . lsp)\n         (tsx-ts-mode        . lsp)\n         (clojure-mode       . lsp))\n  :config\n  (lsp-enable-which-key-integration t))\n#+end_src\n\n#+begin_src emacs-lisp :tangle files/init.el\n(use-package corfu\n  :init\n  (global-corfu-mode)\n  :bind\n  (:map corfu-map\n        (\"RET\" . (lambda ()\n                   (interactive)\n                   (corfu-quit)\n                   (newline-and-indent))))\n  :config\n  (setq corfu-auto t))\n#+end_src\n\nMake sure Emacs can see the environment variables I have in my usual shell:\n\n#+begin_src emacs-lisp :tangle files/init.el\n  (use-package exec-path-from-shell\n    :init\n      (when (memq window-system '(mac ns x))\n        (exec-path-from-shell-initialize)))\n#+end_src\n\nPrevents org-mode from adding extra indentation:\n\n#+begin_src emacs-lisp :tangle files/init.el\n(setq org-src-preserve-indentation t)\n#+end_src\n\nLet's start with some basic project management stuff:\n\n#+begin_src emacs-lisp :tangle files/init.el\n  (use-package magit\n    :init\n    (with-eval-after-load 'project\n      (keymap-set project-prefix-map \"m\" #'magit-project-status)\n      (keymap-set project-prefix-map \"g\" #'consult-ripgrep)\n      (setq project-switch-commands '((magit-project-status \"Magit\")\n                                      (project-find-file \"Find file\")\n                                      (consult-ripgrep \"Find rg\")\n                                      (project-find-dir \"Find dir\")\n                                      (project-shell \"Shell\")))))\n#+end_src\n\n***** Embark\n\n#+begin_src emacs-lisp :tangle files/init.el\n\n(use-package embark\n  :straight t\n  :bind\n  ((\"C-.\" . embark-act)\n   (\"C-h B\" . embark-bindings))\n  :init\n  (setq prefix-help-command #'embark-prefix-help-command))\n\n(use-package embark-consult)\n\n(use-package wgrep)\n\n#+end_src\n\nWeb development.\n\nThe major mode `typescript-ts-mode` comes with Emacs 29.1 and is what I will use\nfor both JavaScript and TypeScript source files. React is also supported.\n\nNew entries are added at the beginning of the list and so will take\nprecedence over any default entries from Emacs.\n\n#+begin_src emacs-lisp :tangle files/init.el\n(dolist (pair '((\"\\\\.js\\\\'\"  . typescript-ts-mode)\n                (\"\\\\.ts\\\\'\"  . typescript-ts-mode)\n                (\"\\\\.jsx\\\\'\" . tsx-ts-mode)\n                (\"\\\\.tsx\\\\'\" . tsx-ts-mode)))\n  (add-to-list 'auto-mode-alist pair))\n#+end_src\n\nThis might be occasionally useful:\n\n#+begin_src emacs-lisp :tangle files/init.el\n(use-package add-node-modules-path\n  :hook ((typescript-ts-mode . add-node-modules-path)))\n#+end_src\n\nSome projects insist on using Prettier and even go\nout of their way to integrate it with Git hooks.\n\nI need to support those projects as otherwise I will\nhave a really tough time.\n\n#+begin_src emacs-lisp :tangle files/init.el\n(use-package prettier-js\n  :hook ((typescript-ts-mode . prettier-js-mode)\n         (tsx-ts-mode . prettier-js-mode)))\n#+end_src\n\nThings I need when I do Clojure(Script) development:\n\n#+begin_src emacs-lisp :tangle files/init.el\n(use-package cider)\n(use-package rainbow-delimiters)\n(use-package paredit)\n\n(use-package clojure-ts-mode\n  :hook ((clojure-ts-mode . rainbow-delimiters-mode)\n         (clojure-ts-mode . paredit-mode)\n         (clojure-ts-mode . cider-mode)))\n#+end_src\n\nSupport for the [[https://janet-lang.org/][Janet]] programming language:\n\nYou need to install Janet first:\n\n#+begin_src\n  brew install janet\n#+end_src\n\n#+begin_src emacs-lisp :tangle files/init.el\n(use-package janet-mode\n  :mode ((\"\\\\.janet\\\\'\" . janet-mode))\n  :hook ((janet-mode . paredit-mode)\n         (janet-mode . rainbow-delimiters-mode)))\n#+end_src\n\nCheck this [[http://danmidwood.com/content/2014/11/21/animated-paredit.html][paredit]] guide out!\n\n*** restclient\n\nThe [[https://github.com/pashky/restclient.el][restclient]] package is a nice alternative to Postman\n\n#+begin_src emacs-lisp :tangle files/init.el\n  (use-package restclient)\n#+end_src\n\n\n*** ob-restclient\n\nI use this package to execute restclient source blocks in org-mode.\n\nNote: you can add a jq filter via a source header e.g. ==:jq .==\n\n#+begin_src emacs-lisp :tangle files/init.el\n(use-package ob-restclient\n  :config\n  (org-babel-do-load-languages\n   'org-babel-load-languages\n   '((restclient . t))))\n#+end_src\n\n*** jq-mode\n\nThis package also provides org-babel support for jq\n\n#+begin_src emacs-lisp :tangle files/init.el\n(use-package jq-mode\n  :config\n  (org-babel-do-load-languages\n   'org-babel-load-languages\n   '((jq . t))))\n#+end_src\n\nMy Emacs configuration file will be put in a standard location:\n\n#+begin_src makefile :tangle Makefile\n$(HOME)/.emacs.d/init.el: files/init.el\n\tmkdir -p $(@D)\n\tcp -f $^ $@\n#+end_src\n\n**** Misc\n\nSee https://emacsredux.com/blog/2024/03/11/tracking-world-time-with-emacs/\n\n#+begin_src emacs-lisp :tangle files/init.el\n(setq world-clock-list\n      '((\"Europe/London\" \"London\")\n        (\"Europe/Brussels\" \"Brussels\")\n        (\"Europe/Kiev\" \"Kiev\")\n        (\"Asia/Seoul\" \"Seoul\")))\n#+end_src\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcustomcommander%2Fdotfiles","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcustomcommander%2Fdotfiles","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcustomcommander%2Fdotfiles/lists"}