[
  {
    "path": ".gitignore",
    "content": "# Ignore everything\n*\n# Except for..\n!.gitignore\n!init.el\n!config.org\n!themes/\n"
  },
  {
    "path": "config.org",
    "content": "#+Title: Yay-Evil distro by Ian Y.E. Pan\n#+Author: Ian Y.E. Pan\n#+Date: 2019\nWelcome! This Emacs \"distro\" is based on my personal Emacs\nconfiguration (on GNU Emacs 26.3). It's unopinionated and was created\nfor general use in mind. The package settings are grouped in a logical\nmanner, and I've documented as detailed as possible what each code\nsnippet does in this file.\n* Settings without corresponding packages\nClean up the UI and enhance some basic defaults defined in \"C Source\nCode\". The variable ~ian/indent-width~ controls the default\nindentation across various programming modes. The default is 4, you\ncan change this variable to 2 or any other indentation width you\nprefer, and the change will be made across all programming language\nmodes including C, C++, Java, Python etc. (Exception: JavaScript\ndefaults to 2-space indent, you can still set it to any other\nindentation width you prefer in the ~web-mode~ section.)\n#+BEGIN_SRC emacs-lisp\n  (use-package emacs\n    :preface\n    (defvar ian/indent-width 4) ; change this value to your preferred width\n    :config\n    (setq frame-title-format '(\"Yay-Evil\") ; Yayyyyy Evil!\n          ring-bell-function 'ignore       ; minimize distraction\n          frame-resize-pixelwise t\n          default-directory \"~/\")\n\n    (tool-bar-mode -1)\n    (menu-bar-mode -1)\n\n    ;; better scrolling experience\n    (setq scroll-margin 0\n          scroll-conservatively 101 ; > 100\n          scroll-preserve-screen-position t\n          auto-window-vscroll nil)\n\n    ;; Always use spaces for indentation\n    (setq-default indent-tabs-mode nil\n                  tab-width ian/indent-width)\n\n    ;; Omit default startup screen\n    (setq inhibit-startup-screen t))\n\n  ;; The Emacs default split doesn't seem too intuitive for most users.\n  (use-package emacs\n    :ensure nil\n    :preface\n    (defun ian/split-and-follow-horizontally ()\n      \"Split window below.\"\n      (interactive)\n      (split-window-below)\n      (other-window 1))\n    (defun ian/split-and-follow-vertically ()\n      \"Split window right.\"\n      (interactive)\n      (split-window-right)\n      (other-window 1))\n    :config\n    (global-set-key (kbd \"C-x 2\") #'ian/split-and-follow-horizontally)\n    (global-set-key (kbd \"C-x 3\") #'ian/split-and-follow-vertically))\n#+END_SRC\n* Configuration for built-in packages\nSince we're using use-package as our package management system, we\nmight as well try to organize under the same syntax as much as\npossible to keep the configuration consistent. The option\n~use-package-always-ensure~ is turned on in ~init.el~, so we'll add\n~:ensure nil~ when configuring the built-in packages.\n#+END_SRC\n** Modernize selection behavior\nReplace the active region just by typing text, just like modern\neditors.\n#+BEGIN_SRC emacs-lisp\n  (use-package delsel\n    :ensure nil\n    :config (delete-selection-mode +1))\n#+END_SRC\n** Disable scroll-bar\n#+BEGIN_SRC emacs-lisp\n  (use-package scroll-bar\n    :ensure nil\n    :config (scroll-bar-mode -1))\n#+END_SRC\n** Enable column numbers\n#+BEGIN_SRC emacs-lisp\n  (use-package simple\n    :ensure nil\n    :config (column-number-mode +1))\n#+END_SRC\n** File-related tweaks\nDon't bother confirming killing processes and don't let backup~ files\nscatter around.\n#+BEGIN_SRC emacs-lisp\n  (use-package files\n    :ensure nil\n    :config\n    (setq confirm-kill-processes nil\n          create-lockfiles nil ; don't create .# files (crashes 'npm start')\n          make-backup-files nil))\n#+END_SRC\n** Automatically refreshes the buffer for changes outside of Emacs\nAuto refreshes every 2 seconds. Don't forget to refresh the version\ncontrol status as well.\n#+BEGIN_SRC emacs-lisp\n  (use-package autorevert\n    :ensure nil\n    :config\n    (global-auto-revert-mode +1)\n    (setq auto-revert-interval 2\n          auto-revert-check-vc-info t\n          global-auto-revert-non-file-buffers t\n          auto-revert-verbose nil))\n#+END_SRC\n** Eldoc: documentation in the mini-buffer\nSlightly shorten eldoc display delay.\n#+BEGIN_SRC emacs-lisp\n  (use-package eldoc\n    :ensure nil\n    :diminish eldoc-mode\n    :config\n    (setq eldoc-idle-delay 0.4))\n#+END_SRC\n** Indentation improvement\nFor Java and C/C++, change the formatting style from GNU (the default)\nto the more standard K&R. Here we also set the indentation width of C,\nC++, Java, and Python to the preferred value defined in\n~ian/indent-width~ (all languages default to 4, except JavaScript,\nwhich is 2, as controlled in ~web-mode~). Of course, you can change\nthe value depending on the language as well.\n#+BEGIN_SRC emacs-lisp\n  ;; C, C++, and Java\n  (use-package cc-vars\n    :ensure nil\n    :config\n    (setq-default c-basic-offset ian/indent-width)\n    (setq c-default-style '((java-mode . \"java\")\n                            (awk-mode . \"awk\")\n                            (other . \"k&r\"))))\n\n  ;; Python (both v2 and v3)\n  (use-package python\n    :ensure nil\n    :config (setq python-indent-offset ian/indent-width))\n#+END_SRC\n** Mouse wheel (track-pad) scroll speed\nBy default, the scrolling is way too fast to be precise and helpful,\nlet's tune it down a little bit.\n#+BEGIN_SRC emacs-lisp\n  (use-package mwheel\n    :ensure nil\n    :config (setq mouse-wheel-scroll-amount '(2 ((shift) . 1))\n                  mouse-wheel-progressive-speed nil))\n#+END_SRC\n** Show matching parentheses\nReduce the highlight delay to instantly.\n#+BEGIN_SRC emacs-lisp\n  (use-package paren\n    :ensure nil\n    :init (setq show-paren-delay 0)\n    :config (show-paren-mode +1))\n#+END_SRC\n** Setting up some frame defaults\nMaximize the frame by default on start-up. Set the font to size 12.\n#+BEGIN_SRC emacs-lisp\n  (use-package frame\n    :preface\n    (defun ian/set-default-font ()\n      (interactive)\n      (when (member \"Consolas\" (font-family-list))\n        (set-face-attribute 'default nil :family \"Consolas\"))\n      (set-face-attribute 'default nil\n                          :height 120\n                          :weight 'normal))\n    :ensure nil\n    :config\n    (setq initial-frame-alist '((fullscreen . maximized)))\n    (ian/set-default-font))\n#+END_SRC\n** Ediff tweaks\nEnter ediff with side-by-side buffers to better compare the\ndifferences.\n#+BEGIN_SRC emacs-lisp\n  (use-package ediff\n    :ensure nil\n    :config\n    (setq ediff-window-setup-function #'ediff-setup-windows-plain)\n    (setq ediff-split-window-function #'split-window-horizontally))\n#+END_SRC\n** Auto-pairing quotes and parentheses etc.\nElectric-pair-mode has improved quite a bit in recent Emacs\nversions. No longer need an extra package for this. It also takes care\nof the new-line-and-push-brace feature.\n#+BEGIN_SRC emacs-lisp\n  (use-package elec-pair\n    :ensure nil\n    :hook (prog-mode . electric-pair-mode))\n#+END_SRC\n** Clean up whitespace on save\n#+BEGIN_SRC emacs-lisp\n  (use-package whitespace\n    :ensure nil\n    :hook (before-save . whitespace-cleanup))\n#+END_SRC\n** Dired tweaks\nDelete intermediate buffers when navigating through dired.\n#+begin_src emacs-lisp\n  (use-package dired\n    :ensure nil\n    :config\n    (setq delete-by-moving-to-trash t)\n    (eval-after-load \"dired\"\n      #'(lambda ()\n          (put 'dired-find-alternate-file 'disabled nil)\n          (define-key dired-mode-map (kbd \"RET\") #'dired-find-alternate-file))))\n#+end_src\n** Dump custom-set-variables to a garbage file and don't load it\n#+BEGIN_SRC emacs-lisp\n  (use-package cus-edit\n    :ensure nil\n    :config\n    (setq custom-file (concat user-emacs-directory \"to-be-dumped.el\")))\n#+END_SRC\n* Third-party packages\nMany Emacsers love having tons of packages -- and that's absolutely\nfine! However, one of the goals of the Yay-Evil distro is to provide\nan essential-only foundation for users to build upon. Therefore, only\nthe most important packages and/or lightweight improvements will be\nincluded here. For example, completion frameworks like Ivy or Helm are\nconsidered heavy by many, yet the built-in Ido serves almost the same\npurpose. The only arguably opinionated package is probably Evil, but\nyou probably saw that coming from the distro name, didn't you ;) ? If\nyou prefer the default keybindings, simply disable the section that\ncontrols the Evil behaviors.\n\nNormally, we need to add ~:ensure t~ to tell ~use-package~ to download packages when it's not available. But since we've added ~use-package-always-ensure~ in ~init.el~, we can omit it.\n** GUI enhancements\n*** Load custom theme\n#+BEGIN_SRC emacs-lisp\n  (add-to-list 'custom-theme-load-path (concat user-emacs-directory \"themes/\"))\n  (load-theme 'wilmersdorf t) ; an orginal theme created by me.\n#+END_SRC\n*** Dashboard welcome page\n#+BEGIN_SRC emacs-lisp\n  (use-package dashboard\n    :config\n    (dashboard-setup-startup-hook)\n    (setq dashboard-startup-banner 'logo\n          dashboard-banner-logo-title \"Yay Evil!\"\n          dashboard-items nil\n          dashboard-set-footer nil))\n#+END_SRC\n*** Syntax highlighting\nLightweight syntax highlighting improvement for numbers and escape\nsequences (e.g. ~\\n, \\t~).\n#+BEGIN_SRC emacs-lisp\n  (use-package highlight-numbers\n    :hook (prog-mode . highlight-numbers-mode))\n\n  (use-package highlight-escape-sequences\n    :hook (prog-mode . hes-mode))\n#+END_SRC\n** Vi keybindings\nI personally find Vi(m) bindings to be the most efficient way of\nediting text (especially code). I also changed the default ~:q~ and\n~:wq~ to be killing current buffer, instead of killing the frame or\nsubsequently killing Emacs.\n#+BEGIN_SRC emacs-lisp\n  (use-package evil\n    :diminish undo-tree-mode\n    :init\n    (setq evil-want-C-u-scroll t\n          evil-want-keybinding nil\n          evil-shift-width ian/indent-width)\n    :hook (after-init . evil-mode)\n    :preface\n    (defun ian/save-and-kill-this-buffer ()\n      (interactive)\n      (save-buffer)\n      (kill-this-buffer))\n    :config\n    (with-eval-after-load 'evil-maps ; avoid conflict with company tooltip selection\n      (define-key evil-insert-state-map (kbd \"C-n\") nil)\n      (define-key evil-insert-state-map (kbd \"C-p\") nil))\n    (evil-ex-define-cmd \"q\" #'kill-this-buffer)\n    (evil-ex-define-cmd \"wq\" #'ian/save-and-kill-this-buffer))\n#+END_SRC\nEvil-collection covers more parts of Emacs that the original Evil\ndoesn't support (e.g. Packages buffer, eshell, calendar etc.)\n#+BEGIN_SRC emacs-lisp\n  (use-package evil-collection\n    :after evil\n    :config\n    (setq evil-collection-company-use-tng nil)\n    (evil-collection-init))\n#+END_SRC\nEmulates tpope's vim commentary package (Use ~gcc~ to comment out a line,\n~gc~ to comment out the target of a motion (for example, ~gcap~ to\ncomment out a paragraph), ~gc~ in visual mode to comment out the\nselection etc.)\n#+BEGIN_SRC emacs-lisp\n  (use-package evil-commentary\n    :after evil\n    :diminish\n    :config (evil-commentary-mode +1))\n#+END_SRC\n** Git Integration\nTell magit to automatically put us in vi-insert-mode when committing a change.\n#+BEGIN_SRC emacs-lisp\n  (use-package magit\n    :bind (\"C-x g\" . magit-status)\n    :config (add-hook 'with-editor-mode-hook #'evil-insert-state))\n#+END_SRC\n** Searching/sorting enhancements & project management\n*** Ido, ido-vertical, ido-ubiquitous and fuzzy matching\nSelecting buffers/files with great efficiency. In my opinion, Ido is\nenough to replace Ivy/Counsel and Helm. We install ido-vertical to get\na better view of the available options (use ~C-n~, ~C-p~ or arrow keys\nto navigate). Ido-ubiquitous (from the ~ido-completing-read+~ package)\nprovides us ido-like completions in describing functions and variables\netc. Fuzzy matching is a nice feature and we have flx-ido for that\npurpose.\n#+BEGIN_SRC emacs-lisp\n  (use-package ido\n    :config\n    (ido-mode +1)\n    (setq ido-everywhere t\n          ido-enable-flex-matching t))\n\n  (use-package ido-vertical-mode\n    :config\n    (ido-vertical-mode +1)\n    (setq ido-vertical-define-keys 'C-n-C-p-up-and-down))\n\n  (use-package ido-completing-read+ :config (ido-ubiquitous-mode +1))\n\n  (use-package flx-ido :config (flx-ido-mode +1))\n#+END_SRC\n** Programming language support and utilities\n*** Company for auto-completion\nUse ~C-n~ and ~C-p~ to navigate the tooltip.\n#+BEGIN_SRC emacs-lisp\n  (use-package company\n    :diminish company-mode\n    :hook (prog-mode . company-mode)\n    :config\n    (setq company-minimum-prefix-length 1\n          company-idle-delay 0.1\n          company-selection-wrap-around t\n          company-tooltip-align-annotations t\n          company-frontends '(company-pseudo-tooltip-frontend ; show tooltip even for single candidate\n                              company-echo-metadata-frontend))\n    (define-key company-active-map (kbd \"C-n\") 'company-select-next)\n    (define-key company-active-map (kbd \"C-p\") 'company-select-previous))\n#+END_SRC\n*** Flycheck\nA modern on-the-fly syntax checking extension -- absolute essential\n#+BEGIN_SRC emacs-lisp\n  (use-package flycheck :config (global-flycheck-mode +1))\n#+END_SRC\n*** Org Mode\nSome minimal org mode tweaks: org-bullets gives our headings (h1, h2,\nh3...) a more visually pleasing look.\n#+BEGIN_SRC emacs-lisp\n  (use-package org\n    :hook ((org-mode . visual-line-mode)\n           (org-mode . org-indent-mode)))\n\n  (use-package org-bullets :hook (org-mode . org-bullets-mode))\n#+END_SRC\n*** Useful major modes\nMarkdown mode and Web mode, the latter covers our usages of HTML/CSS/JS/JSX/TS/TSX/JSON.\n#+BEGIN_SRC emacs-lisp\n  (use-package markdown-mode\n    :hook (markdown-mode . visual-line-mode))\n\n  (use-package web-mode\n    :mode ((\"\\\\.html?\\\\'\" . web-mode)\n           (\"\\\\.css\\\\'\"   . web-mode)\n           (\"\\\\.jsx?\\\\'\"  . web-mode)\n           (\"\\\\.tsx?\\\\'\"  . web-mode)\n           (\"\\\\.json\\\\'\"  . web-mode))\n    :config\n    (setq web-mode-markup-indent-offset 2) ; HTML\n    (setq web-mode-css-indent-offset 2)    ; CSS\n    (setq web-mode-code-indent-offset 2)   ; JS/JSX/TS/TSX\n    (setq web-mode-content-types-alist '((\"jsx\" . \"\\\\.js[x]?\\\\'\"))))\n#+END_SRC\n** Miscellaneous\n*** Diminish minor modes\nThe diminish package is used to hide unimportant minor modes in the\nmodeline. It provides the ~:diminish~ keyword we've been using in\nother use-package declarations.\n#+BEGIN_SRC emacs-lisp\n  (use-package diminish\n    :demand t)\n#+END_SRC\n*** Which-key\nProvides us with hints on available keystroke combinations.\n#+BEGIN_SRC emacs-lisp\n  (use-package which-key\n    :diminish which-key-mode\n    :config\n    (which-key-mode +1)\n    (setq which-key-idle-delay 0.4\n          which-key-idle-secondary-delay 0.4))\n#+END_SRC\n*** Configure PATH on macOS\n#+BEGIN_SRC emacs-lisp\n  (use-package exec-path-from-shell\n    :config (when (memq window-system '(mac ns x))\n              (exec-path-from-shell-initialize)))\n#+END_SRC\n"
  },
  {
    "path": "init.el",
    "content": ";;; init.el --- Emacs init file\n;;  Author: Ian Y.E. Pan\n;;; Commentary:\n;;; A lightweight Emacs config containing only the essentials: shipped with a custom theme!\n;;; Code:\n(defvar file-name-handler-alist-original file-name-handler-alist)\n\n(setq gc-cons-threshold most-positive-fixnum\n      gc-cons-percentage 0.6\n      file-name-handler-alist nil\n      site-run-file nil)\n\n(defvar ian/gc-cons-threshold 100000000)\n\n(add-hook 'emacs-startup-hook ; hook run after loading init files\n          (lambda ()\n            (setq gc-cons-threshold ian/gc-cons-threshold\n                  gc-cons-percentage 0.1\n                  file-name-handler-alist file-name-handler-alist-original)))\n\n(add-hook 'minibuffer-setup-hook (lambda ()\n                                   (setq gc-cons-threshold (* ian/gc-cons-threshold 2))))\n(add-hook 'minibuffer-exit-hook (lambda ()\n                                  (garbage-collect)\n                                  (setq gc-cons-threshold ian/gc-cons-threshold)))\n\n(require 'package)\n(add-to-list 'package-archives '(\"gnu\" . \"https://elpa.gnu.org/packages/\"))\n(add-to-list 'package-archives '(\"melpa\" . \"https://melpa.org/packages/\"))\n(add-to-list 'package-archives '(\"org\" . \"https://orgmode.org/elpa/\"))\n(setq package-enable-at-startup nil)\n(package-initialize)\n\n;; workaround bug in Emacs 26.2\n(setq gnutls-algorithm-priority \"NORMAL:-VERS-TLS1.3\")\n\n;; Setting up the package manager. Install if missing.\n(unless (package-installed-p 'use-package)\n  (package-refresh-contents)\n  (package-install 'use-package))\n(eval-and-compile\n  (setq use-package-always-ensure t))\n\n;;; Emacs 28+ (native-comp) stuff\n(when (and (fboundp 'native-comp-available-p) (native-comp-available-p))\n  (progn\n    (setq native-comp-async-report-warnings-errors nil)\n    (setq native-comp-deferred-compilation t)\n    (add-to-list 'native-comp-eln-load-path (expand-file-name \"eln-cache/\" user-emacs-directory))\n    (setq package-native-compile t)))\n\n;; Load main config file \"./config.org\"\n(require 'org)\n(org-babel-load-file (expand-file-name (concat user-emacs-directory \"config.org\")))\n\n(provide 'init)\n;;; init.el ends here\n"
  }
]