--- /dev/null
+Subproject commit 9407a57779933c4745fbace18a64be12a120a547
--- /dev/null
+(custom-set-variables
+ ;; custom-set-variables was added by Custom.
+ ;; If you edit it by hand, you could mess it up, so be careful.
+ ;; Your init file should contain only one such instance.
+ ;; If there is more than one, they won't work right.
+ '(comint-process-echoes t)
+ '(company-minimum-prefix-length 2)
+ '(dap-internal-terminal 'dap-internal-terminal-shell)
+ '(dap-print-io t)
+ '(dap-ui-repl-prompt "?- ")
+ '(enable-recursive-minibuffers t)
+ '(flymake-proc-allowed-file-name-masks
+ '(("\\.\\(?:c\\(?:pp\\|xx\\|\\+\\+\\)?\\|CC\\)\\'" flymake-proc-simple-make-init nil flymake-proc-real-file-name-considering-includes)
+ ("\\.xml\\'" flymake-proc-xml-init nil nil)
+ ("\\.html?\\'" flymake-proc-xml-init nil nil)
+ ("\\.cs\\'" flymake-proc-simple-make-init nil nil)
+ ("\\.php[345]?\\'" flymake-proc-php-init nil nil)
+ ("\\.h\\'" flymake-proc-master-make-header-init flymake-proc-master-cleanup nil)
+ ("\\.java\\'" flymake-proc-simple-make-java-init flymake-proc-simple-java-cleanup nil)
+ ("[0-9]+\\.tex\\'" flymake-proc-master-tex-init flymake-proc-master-cleanup nil)
+ ("\\.tex\\'" flymake-proc-simple-tex-init nil nil)
+ ("\\.idl\\'" flymake-proc-simple-make-init nil nil)))
+ '(max-specpdl-size 10000)
+ '(mct-apply-completion-stripes t)
+ '(mct-hide-completion-mode-line t)
+ '(mct-live-update-delay 0.6)
+ '(org-agenda-files '("~/inbox.org"))
+ '(org-agenda-start-on-weekday 0)
+ '(org-default-notes-file "~/inbox.org")
+ '(package-selected-packages
+ '(cape corfu speed-type json-mode json-navigator flymake-swi-prolog package-lint package-lint-flymake all-the-icons-completion mct dap-ui auto-package-update zenburn-theme yasnippet-snippets yaml-mode yagist windswap whole-line-or-region whitespace-cleanup-mode which-key w3m vterm vlf vertico use-package unfill tramp terraform-mode terraform-doc symbol-overlay switch-window smartparens sketch-mode semi rustic rg reformatter rainbow-delimiters protobuf-mode proof-general pdf-tools page-break-lines org-superstar orderless ob-prolog ns-auto-titlebar no-littering multiple-cursors move-dup mode-line-bell markdown-toc markdown-changelog marginalia magit-todos lsp-ui lsp-java lsp-haskell lorem-ipsum list-unicode-display keyfreq keycast iedit idris-mode ibuffer-vc ibuffer-projectile ialign htmlize highlight-escape-sequences helpful graphviz-dot-mode go-mode gnu-elpa-keyring-update gitignore-mode github-review github-clone gitconfig-mode git-timemachine git-blamed ggtags fullframe forge flycheck-golangci-lint expand-region exec-path-from-shell esup erlang epresent embark-consult emacsql-sqlite3 elixir-mode ediprolog dtache dockerfile-mode disable-mouse diminish diff-hl define-word default-text-scale consult-flycheck company-quickhelp company-coq company-auctex command-log-mode bug-reference-github browse-kill-ring browse-at-remote beacon auctex-latexmk anzu all-the-icons alert affe ace-jump-mode academic-phrases))
+ '(savehist-additional-variables '(esy/org-capture-to-project-heading-history-list)))
+(custom-set-faces
+ ;; custom-set-faces was added by Custom.
+ ;; If you edit it by hand, you could mess it up, so be careful.
+ ;; Your init file should contain only one such instance.
+ ;; If there is more than one, they won't work right.
+ '(aw-leading-char-face ((t (:inherit (bold modus-themes-reset-soft) :foreground "#fe6060" :height 1)))))
--- /dev/null
+;;; init.el --- Load the full configuration -*- lexical-binding: t -*-
+;;; Commentary:
+
+;;; Code:
+
+;; Produce backtraces when errors occur: can be helpful to diagnose startup issues
+;;(setq debug-on-error t)
+
+
+(let ((normal-gc-cons-threshold (* 20 1024 1024))
+ (init-gc-cons-threshold (* 128 1024 1024)))
+ (setq gc-cons-threshold init-gc-cons-threshold)
+ (add-hook 'emacs-startup-hook
+ (lambda () (setq gc-cons-threshold normal-gc-cons-threshold))))
+
+(require 'package)
+
+(add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/"))
+
+(package-initialize)
+
+(unless (package-installed-p 'use-package)
+ ((package-refresh-contents)
+ (package-install 'use-package)))
+
+(global-set-key (kbd "C-s-f") 'toggle-frame-fullscreen)
+
+(require 'use-package)
+
+(setq use-package-always-ensure t)
+
+(setq-default indent-tabs-mode nil)
+
+(use-package auto-package-update
+ :custom
+ (auto-package-update-interval 7)
+ (auto-package-update-prompt-before-update t)
+ (auto-package-update-hide-results t)
+ :config
+ (auto-package-update-maybe)
+ (auto-package-update-at-time "09:00"))
+
+(use-package no-littering)
+
+(setq auto-save-file-name-transforms
+ `((".*" ,(no-littering-expand-var-file-name "auto-save/") t)))
+
+(setq custom-file (no-littering-expand-etc-file-name "custom.el"))
+(load custom-file 'noerror 'nomessage)
+
+ (when (fboundp 'startup-redirect-eln-cache)
+ (startup-redirect-eln-cache
+ (convert-standard-filename
+ (expand-file-name "var/eln-cache/" user-emacs-directory))))
+
+(load-theme 'modus-vivendi)
+(modus-themes-load-vivendi)
+
+(add-to-list 'load-path (expand-file-name "lisp" user-emacs-directory))
+
+(recentf-mode 1)
+
+(setq history-length 25)
+(savehist-mode 1)
+
+(save-place-mode 1)
+
+(add-hook 'after-init-hook 'exec-path-from-shell-initialize)
+
+(setq use-file-dialog nil)
+(setq use-dialog-box nil)
+(setq inhibit-startup-screen t)
+
+(menu-bar-mode -1)
+(tool-bar-mode -1)
+(set-scroll-bar-mode nil)
+(setq ns-use-native-fullscreen t)
+
+
+(require 'wgrep)
+(require 'transient)
+(require 'rg)
+(rg-enable-default-bindings)
+
+
+(add-hook 'after-init-hook 'global-auto-revert-mode)
+(setq global-auto-revert-non-file-buffers t
+ auto-revert-verbose nil)
+
+(add-hook 'after-init-hook 'transient-mark-mode)
+
+(add-hook 'prog-mode-hook 'rainbow-delimiters-mode)
+(add-hook 'prog-mode-hook 'display-line-numbers-mode)
+
+(add-hook 'after-init-hook 'show-paren-mode)
+
+(require 'symbol-overlay)
+(global-set-key (kbd "M-i") 'symbol-overlay-put)
+
+
+(use-package move-dup
+ :bind (("M-p" . move-dup-move-lines-up)
+ ("M-n" . move-dup-move-lines-down)
+ ("s-p" . move-dup-duplicate-up)
+ ("s-n" . move-dup-duplicate-down)))
+
+(require 'which-key)
+(add-hook 'after-init-hook 'which-key-mode)
+
+(require 'whitespace-cleanup-mode)
+(add-hook 'after-init-hook 'global-whitespace-cleanup-mode)
+
+(global-set-key [remap just-one-space] 'cycle-spacing)
+
+(require 'diff-hl)
+(add-hook 'after-init-hook 'global-diff-hl-mode)
+
+(use-package magit
+ :bind (("C-x g" . magit-status))
+ :init
+ (add-hook 'magit-post-refresh-hook #'diff-hl-magit-post-refresh))
+
+
+(require 'forge)
+
+(require 'pdf-tools)
+(add-hook 'pdf-view-mode-hook 'pdf-tools-install)
+
+(require 'ialign)
+
+(global-set-key (kbd "C-x l") #'ialign)
+
+(global-set-key (kbd "C-x m") #'execute-extended-command) ; bound to #'compose-mail by default
+
+(require 'keycast)
+
+(require 'publish)
+
+
+(use-package dtache
+ :custom (dtache-notification-function #'dtache-state-transitionion-echo-message)
+ :init (dtache-setup)
+ :bind (([remap async-shell-command] . dtache-shell-command)))
+
+(add-to-list 'auto-mode-alist '("\\.pl\\'" . prolog-mode))
+(add-to-list 'auto-mode-alist '("\\.plt\\'" . prolog-mode))
+
+(define-derived-mode dapscript-mode
+ prolog-mode "DAP script"
+ "Major mode for dapscript source files."
+ (flymake-mode))
+
+(add-to-list 'auto-mode-alist '("\\.dapscript\\'" . dapscript-mode))
+
+(use-package vterm)
+(use-package lsp-mode)
+(use-package lsp-ui)
+(use-package dap-mode)
+
+(global-set-key (kbd "C-c d") 'dap-hydra)
+
+(require 'dap-ui)
+(require 'dap-swi-prolog)
+
+(require 'helpful)
+(global-set-key (kbd "C-h f") #'helpful-callable)
+(global-set-key (kbd "C-h v") #'helpful-variable)
+(global-set-key (kbd "C-h k") #'helpful-key)
+
+
+(use-package corfu
+ :custom
+ (corfu-cycle t)
+ (corfu-auto t)
+ :init
+ (corfu-global-mode))
+
+(use-package dabbrev
+ :bind (("M-/" . dabbrev-completion)
+ ("C-M-/" . dabbrev-expand)))
+
+(use-package cape
+ :init
+ (add-to-list 'completion-at-point-functions #'cape-file)
+ (add-to-list 'completion-at-point-functions #'cape-dabbrev))
+
+(use-package reformatter)
+
+(setq read-extended-command-predicate 'command-completion-default-include-p)
+(use-package mct)
+(add-hook 'after-init-hook 'mct-minibuffer-mode)
+
+(defun esy/choose-completion-no-exit ()
+ "Hack to circumvent 'mct-choose-completion-no-exit' leaving the minibuffer."
+ (interactive)
+ (mct-choose-completion-no-exit)
+ (mct-focus-minibuffer))
+
+(defun esy/edit-completion ()
+ "Hack to circumvent 'mct-edit-completion' leaving the minibuffer."
+ (interactive)
+ (mct-edit-completion)
+ (mct-focus-minibuffer))
+
+(define-key mct-minibuffer-completion-list-map [remap mct-choose-completion-no-exit] #'esy/choose-completion-no-exit)
+(define-key mct-minibuffer-completion-list-map [remap mct-edit-completion] #'esy/edit-completion)
+
+(use-package marginalia
+ :init
+ (marginalia-mode))
+
+(use-package orderless
+ :custom (completion-styles '(orderless)))
+
+(use-package all-the-icons
+ :if (display-graphic-p))
+
+(use-package all-the-icons-completion
+ :config (all-the-icons-completion-mode))
+
+(add-hook 'marginalia-mode-hook #'all-the-icons-completion-marginalia-setup)
+
+(add-hook 'prog-mode-hook 'flymake-mode)
+
+(require 'consult)
+(require 'consult-imenu)
+
+(global-set-key [remap switch-to-buffer] 'consult-buffer)
+(global-set-key [remap switch-to-buffer-other-window] 'consult-buffer-other-window)
+(global-set-key [remap switch-to-buffer-other-frame] 'consult-buffer-other-frame)
+(global-set-key [remap goto-line] 'consult-goto-line)
+
+(global-set-key (kbd "C-c !") 'consult-flymake)
+
+(defvar esy/inbox-path "~/inbox.org"
+ "Path to my Org mode inbox file.")
+
+(defvar esy/org-capture-to-project-heading-history-list nil
+ "History list for 'esy/org-capture-to-project-heading'.")
+
+(setq savehist-additional-variables (list 'esy/org-capture-to-project-heading-history-list))
+
+(defun esy/org-capture-to-project-heading ()
+ "Prompt for a projects and capture a related task."
+ (let* ((projects
+ (org-map-entries `(lambda () (nth 4 (org-heading-components)))
+ "+project+LEVEL=2" (list esy/inbox-path)))
+ (choice (completing-read "Project: " projects nil t nil 'esy/org-capture-to-project-heading-history-list)))
+ (org-capture-set-target-location (list 'file+olp esy/inbox-path "Projects" choice))))
+
+
+(setq org-capture-templates '(("t" "Todo [inbox]" entry
+ (file+headline esy/inbox-path "Tasks")
+ "** TODO %? %^g\n %i\n %t\n %a\n" :prepend t)
+ ("n" "New Project" entry
+ (file+headline esy/inbox-path "Projects")
+ "** %? %^g\n %i\n" :prepend t)
+ ("p" "New Project Task" entry
+ (file+function esy/inbox-path esy/org-capture-to-project-heading)
+ "*** TODO %?\n:PROPERTIES:\n:CreatedAt: %t\n:CapturedAt: %a\n:END:\n%i\n" :prepend t)))
+
+(global-set-key (kbd "C-c c") 'org-capture)
+
+
+(use-package org-superstar)
+(add-hook 'org-mode-hook #'org-superstar-mode)
+
+(use-package embark
+ :bind
+ (("C-." . embark-act))
+ :config
+ ;; Hide the mode line of the Embark live/completions buffers
+ (add-to-list 'display-buffer-alist
+ '("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
+ nil
+ (window-parameters (mode-line-format . none)))))
+
+;; Consult users will also want the embark-consult package.
+(use-package embark-consult
+ :ensure t
+ :after (embark consult)
+ :demand t ; only necessary if you have the hook below
+ :hook
+ (embark-collect-mode . consult-preview-at-point-mode))
+
+(require 'windmove)
+(windmove-default-keybindings 'meta)
+
+(use-package ace-window
+ :bind
+ (("C-x o" . ace-window))
+ :config
+ (setq aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l)))
+
+(require 'beacon)
+(beacon-mode 1)
+(setq beacon-color "magenta")
+
+(setq ring-bell-function 'ignore)
+
+(defun esy/pin-buffer ()
+ "Pin buffer to current window."
+ (interactive)
+ (message
+ (if (let (window (get-buffer-window (current-buffer)))
+ (set-window-dedicated-p window (not (window-dedicated-p window))))
+ "pinned buffer" "un-pinned buffer")
+ ))
+
+(require 'company)
+
+(add-to-list 'load-path "~/.emacs.d/checkouts/flymake-swi-prolog")
+
+(require 'flymake-swi-prolog)
+
+(add-hook 'prolog-mode-hook #'flymake-swi-prolog-setup-backend)
+
+(add-to-list 'auto-mode-alist '("\\.json\\'" . json-mode))
+
+(global-set-key [remap transpose-chars] #'backward-kill-word)
+
+(provide 'init)
+;;; init.el ends here
--- /dev/null
+;;; aide.el --- An Emacs front end for GPT APIs like OpenAI -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 Junji Zhi
+
+;; Author: Junji Zhi
+;; Keywords: gpt-3 openai
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Simple wrapper to call GPT APIs
+;;
+;; For details, please see http://github.com/junjizhi/aide.el
+
+;;; Code:
+
+(require 'request)
+
+(defgroup aide nil
+ "aide.el custom settings"
+ :group 'external
+ :prefix "aide-")
+
+(defcustom aide-max-tokens 100
+ "The max-tokens paramater that aide.el sends to OpenAI API."
+ :type 'integer
+ :group 'aide)
+
+(defcustom aide-temperature 0
+ "The temperature paramater that aide.el sends to OpenAI API."
+ :type 'float
+ :group 'aide)
+
+(defcustom aide-top-p 0.1
+ "The top-p paramater that aide.el sends to OpenAI API."
+ :type 'float
+ :group 'aide)
+
+(defcustom aide-frequency-penalty 0
+ "The frequency_penalty paramater that aide.el sends to OpenAI API."
+ :type 'float
+ :group 'aide)
+
+(defcustom aide-presence-penalty 0
+ "The presence_penalty paramater that aide.el sends to OpenAI API."
+ :type 'float
+ :group 'aide)
+
+
+(defun aide-openai-complete (api-key prompt)
+ "Return the prompt answer from OpenAI API.
+API-KEY is the OpenAI API key.
+PROMPT is the prompt string we send to the API."
+ (let ((result nil)
+ (auth-value (format "Bearer %s" api-key)))
+ (request
+ "https://api.openai.com/v1/engines/davinci/completions"
+ :type "POST"
+ :data (json-encode `(("prompt" . ,prompt)
+ ("max_tokens" . ,aide-max-tokens)
+ ("temperature" . ,aide-temperature)
+ ("frequency_penalty" . ,aide-frequency-penalty)
+ ("presence_penalty" . ,aide-presence-penalty)
+ ("top_p" . ,aide-top-p)))
+ :headers `(("Authorization" . ,auth-value) ("Content-Type" . "application/json"))
+ :sync t
+ :parser 'json-read
+ :success (cl-function
+ (lambda (&key data &allow-other-keys)
+ (setq result (alist-get 'text (elt (alist-get 'choices data) 0))))))
+ result))
+
+(defun aide-openai-complete-region (start end)
+ "Send the region to OpenAI autocomplete engine and get the result.
+START and END are selected region boundaries."
+ (interactive "r")
+ (let* ((region (buffer-substring-no-properties start end))
+ (result (aide--openai-complete-string region)))
+ (message "%s" result)))
+
+(defun aide-openai-complete-region-insert (start end)
+ "Send the region to OpenAI and insert the result to the end of buffer.
+START and END are selected region boundaries."
+ (interactive "r")
+ (let* ((region (buffer-substring-no-properties start end))
+ (result (aide--openai-complete-string region))
+ original-point)
+ (goto-char (point-max))
+ (setq original-point (point))
+ (if result
+ (progn
+ (insert "\n" result)
+ (fill-paragraph)
+ (let ((x (make-overlay original-point (point-max))))
+ (overlay-put x 'face '(:foreground "orange red")))
+ result)
+ (message "Empty result"))))
+
+(defun aide-openai-complete-buffer-insert ()
+ "Send the ENTIRE buffer to OpenAI and insert the result to the end of buffer."
+ (interactive)
+ (let (region
+ result
+ original-point)
+ (setq region (buffer-substring-no-properties (point-min) (point-max)))
+ (setq result (aide--openai-complete-string region))
+ (goto-char (point-max))
+ (setq original-point (point))
+ (if result
+ (progn
+ (insert "\n" result)
+ (fill-paragraph)
+ (let ((x (make-overlay original-point (point-max))))
+ (overlay-put x 'face '(:foreground "orange red")))
+ result)
+ (message "Empty result"))))
+
+(defun aide-openai-tldr-region (start end)
+ "Send the region to OpenAI autocomplete engine and get the TLDR result.
+START and END are selected region boundaries."
+ (interactive "r")
+ (let* ((region (buffer-substring-no-properties start end))
+ (result (aide--openai-complete-string (concat region "\n\n tl;dr:"))))
+ (message "%s" result)))
+
+(defun aide-openai-edits (api-key instruction input)
+ "Return the edits answer from OpenAI API.
+API-KEY is the OpenAI API key.
+INSTRUCTION and INPUT are the two params we send to the API."
+ (let ((result nil)
+ (auth-value (format "Bearer %s" api-key)))
+ (request
+ "https://api.openai.com/v1/engines/text-davinci-edit-001/edits"
+ :type "POST"
+ :data (json-encode `(("input" . ,input)
+ ("instruction" . ,instruction)
+ ("temperature" . 0.9)))
+ :headers `(("Authorization" . ,auth-value)
+ ("Content-Type" . "application/json"))
+ :sync t
+ :parser 'json-read
+ :success (cl-function
+ (lambda (&key data &allow-other-keys)
+ (setq result (alist-get 'text (elt (alist-get 'choices data) 0))))))
+ result))
+
+(defun aide-openai-edits-region-insert (start end)
+ "Send the region to OpenAI edits and insert the result to the end of region.
+START and END are selected region boundaries."
+ (interactive "r")
+ (let* ((region (buffer-substring-no-properties start end))
+ (result (aide-openai-edits openai-api-key "Rephrase the text" region)))
+ (goto-char end)
+ (if result
+ (progn
+ (insert "\n" result)
+ (fill-paragraph)
+ (let ((x (make-overlay end (point))))
+ (overlay-put x 'face '(:foreground "orange red")))
+ result)
+ (message "Empty result"))))
+
+(defun aide-openai-edits-region-replace (start end)
+ "Send the region to OpenAI edits and replace the region.
+START and END are selected region boundaries.
+The original content will be stored in the kill ring."
+ (interactive "r")
+ (let* ((region (buffer-substring-no-properties start end))
+ (result (aide-openai-edits openai-api-key "Rephrase the text" region)))
+ (goto-char end)
+ (if result
+ (progn
+ (kill-region start end)
+ (insert "\n" result)
+ (fill-paragraph)
+ (let ((x (make-overlay end (point))))
+ (overlay-put x 'face '(:foreground "orange red")))
+ result)
+ (message "Empty result"))))
+
+;; private
+
+(defun aide--openai-complete-string (string)
+ (aide-openai-complete openai-api-key string))
+
+(provide 'aide)
+;;; aide.el ends here
--- /dev/null
+;;; dap-swi-prolog.el --- Debug Adapter Protocol mode for SWI-Prolog -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2022 Eshel Yaron
+
+;; Author: Eshel Yaron <eshelshay.yaron@gmail.com>
+;; Keywords: languages
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+;; URL: https://github.com/yyoncho/dap-mode
+;; Package-Requires: ((emacs "25.1") (dash "2.14.1") (lsp-mode "4.0"))
+;; Version: 0.3
+
+;;; Commentary:
+;; Adapter for https://www.swi-prolog.org
+
+;;; Code:
+
+(require 'dap-mode)
+
+(defcustom dap-swi-prolog-debug-program
+ '("swipl" "-g" "[library(debug_adapter/main)]" "-t" "halt")
+ "The path to the SWI-Prolog debug adapter."
+ :group 'dap-swi-prolog
+ :type '(repeat string))
+
+(defun dap-swi-prolog--populate-start-file-args (conf)
+ "Populate CONF with the required arguments."
+ (let ((conf (-> conf
+ (dap--put-if-absent :dap-server-path dap-swi-prolog-debug-program)
+ (dap--put-if-absent :type "swi-prolog")
+ (dap--put-if-absent :cwd default-directory)
+ (dap--put-if-absent :module (buffer-file-name))
+ (dap--put-if-absent :goal (read-string "?- " nil nil "true"))
+ (dap--put-if-absent :name "SWI-Prolog Debug"))))
+ conf))
+
+(dap-register-debug-provider "swi-prolog" #'dap-swi-prolog--populate-start-file-args)
+
+(dap-register-debug-template "SWI-Prolog Run Configuration"
+ (list :type "swi-prolog"
+ :request "launch"
+ :name "SWI-Prolog::Run"))
+(dap-register-debug-template "SWI-Prolog Start Terminal"
+ (list :type "swi-prolog"
+ :goal "$run_in_terminal"
+ :request "launch"
+ :name "SWI-Prolog::Terminal"))
+
+(defun dap-swi-prolog--populate-start-tcp-args (conf)
+ "Populate CONF with the required arguments."
+ (let ((conf (-> conf
+ (dap--put-if-absent :host "localhost")
+ (dap--put-if-absent :debugServer 3443)
+ (dap--put-if-absent :request "attach")
+ (dap--put-if-absent :name "SWI-Prolog Debug"))))
+ conf))
+
+(dap-register-debug-provider "swi-prolog-tcp" #'dap-swi-prolog--populate-start-tcp-args)
+
+(provide 'dap-swi-prolog)
+;;; dap-swi-prolog.el ends here
--- /dev/null
+;;; init-benchmarking.el --- Measure startup and require times -*- lexical-binding: t -*-
+;;; Commentary:
+;;; Code:
+
+(defun sanityinc/time-subtract-millis (b a)
+ (* 1000.0 (float-time (time-subtract b a))))
+
+
+(defvar sanityinc/require-times nil
+ "A list of (FEATURE LOAD-START-TIME LOAD-DURATION).
+LOAD-DURATION is the time taken in milliseconds to load FEATURE.")
+
+(defun sanityinc/require-times-wrapper (orig feature &rest args)
+ "Note in `sanityinc/require-times' the time taken to require each feature."
+ (let* ((already-loaded (memq feature features))
+ (require-start-time (and (not already-loaded) (current-time))))
+ (prog1
+ (apply orig feature args)
+ (when (and (not already-loaded) (memq feature features))
+ (let ((time (sanityinc/time-subtract-millis (current-time) require-start-time)))
+ (add-to-list 'sanityinc/require-times
+ (list feature require-start-time time)
+ t))))))
+
+(advice-add 'require :around 'sanityinc/require-times-wrapper)
+
+
+(define-derived-mode sanityinc/require-times-mode tabulated-list-mode "Require-Times"
+ "Show times taken to `require' packages."
+ (setq tabulated-list-format
+ [("Start time (ms)" 20 sanityinc/require-times-sort-by-start-time-pred)
+ ("Feature" 30 t)
+ ("Time (ms)" 12 sanityinc/require-times-sort-by-load-time-pred)])
+ (setq tabulated-list-sort-key (cons "Start time (ms)" nil))
+ ;; (setq tabulated-list-padding 2)
+ (setq tabulated-list-entries #'sanityinc/require-times-tabulated-list-entries)
+ (tabulated-list-init-header)
+ (when (fboundp 'tablist-minor-mode)
+ (tablist-minor-mode)))
+
+(defun sanityinc/require-times-sort-by-start-time-pred (entry1 entry2)
+ (< (string-to-number (elt (nth 1 entry1) 0))
+ (string-to-number (elt (nth 1 entry2) 0))))
+
+(defun sanityinc/require-times-sort-by-load-time-pred (entry1 entry2)
+ (> (string-to-number (elt (nth 1 entry1) 2))
+ (string-to-number (elt (nth 1 entry2) 2))))
+
+(defun sanityinc/require-times-tabulated-list-entries ()
+ (cl-loop for (feature start-time millis) in sanityinc/require-times
+ with order = 0
+ do (incf order)
+ collect (list order
+ (vector
+ (format "%.3f" (sanityinc/time-subtract-millis start-time before-init-time))
+ (symbol-name feature)
+ (format "%.3f" millis)))))
+
+(defun sanityinc/require-times ()
+ "Show a tabular view of how long various libraries took to load."
+ (interactive)
+ (with-current-buffer (get-buffer-create "*Require Times*")
+ (sanityinc/require-times-mode)
+ (tabulated-list-revert)
+ (display-buffer (current-buffer))))
+
+
+(defun sanityinc/show-init-time ()
+ (message "init completed in %.2fms"
+ (sanityinc/time-subtract-millis after-init-time before-init-time)))
+
+(add-hook 'after-init-hook 'sanityinc/show-init-time)
+
+(provide 'init-benchmarking)
+;;; init-benchmarking.el ends here
--- /dev/null
+;;; init-company.el --- Completion with company -*- lexical-binding: t -*-
+;;; Commentary:
+;;; Code:
+
+;; WAITING: haskell-mode sets tags-table-list globally, breaks tags-completion-at-point-function
+;; TODO Default sort order should place [a-z] before punctuation
+
+(setq tab-always-indent 'complete)
+(add-to-list 'completion-styles 'initials t)
+
+(when (maybe-require-package 'company)
+ (add-hook 'after-init-hook 'global-company-mode)
+ (with-eval-after-load 'company
+ (diminish 'company-mode)
+; (define-key company-mode-map (kbd "M-/") 'company-complete)
+ (define-key company-mode-map [remap completion-at-point] 'company-complete)
+ (define-key company-mode-map [remap indent-for-tab-command] 'company-indent-or-complete-common)
+; (define-key company-active-map (kbd "M-/") 'company-other-backend)
+ (define-key company-active-map (kbd "C-n") 'company-select-next)
+ (define-key company-active-map (kbd "C-p") 'company-select-previous)
+ (define-key company-active-map (kbd "C-d") 'company-show-doc-buffer)
+ (define-key company-active-map (kbd "M-.") 'company-show-location)
+ (setq-default company-dabbrev-other-buffers 'all
+ company-tooltip-align-annotations t))
+ (global-set-key (kbd "M-C-/") 'company-complete)
+ (when (maybe-require-package 'company-quickhelp)
+ (add-hook 'after-init-hook 'company-quickhelp-mode)))
+
+(provide 'init-company)
+;;; init-company.el ends here
--- /dev/null
+;;; init-compile.el --- Helpers for M-x compile -*- lexical-binding: t -*-
+;;; Commentary:
+;;; Code:
+
+(setq-default compilation-scroll-output t)
+
+(require-package 'alert)
+
+;; Customize `alert-default-style' to get messages after compilation
+
+(defun sanityinc/alert-after-compilation-finish (buf result)
+ "Use `alert' to report compilation RESULT if BUF is hidden."
+ (when (buffer-live-p buf)
+ (unless (catch 'is-visible
+ (walk-windows (lambda (w)
+ (when (eq (window-buffer w) buf)
+ (throw 'is-visible t))))
+ nil)
+ (alert (concat "Compilation " result)
+ :buffer buf
+ :category 'compilation))))
+
+(with-eval-after-load 'compile
+ (add-hook 'compilation-finish-functions
+ 'sanityinc/alert-after-compilation-finish))
+
+(defvar sanityinc/last-compilation-buffer nil
+ "The last buffer in which compilation took place.")
+
+(with-eval-after-load 'compile
+ (defun sanityinc/save-compilation-buffer (&rest _)
+ "Save the compilation buffer to find it later."
+ (setq sanityinc/last-compilation-buffer next-error-last-buffer))
+ (advice-add 'compilation-start :after 'sanityinc/save-compilation-buffer)
+
+ (defun sanityinc/find-prev-compilation (orig &optional edit-command)
+ "Find the previous compilation buffer, if present, and recompile there."
+ (if (and (null edit-command)
+ (not (derived-mode-p 'compilation-mode))
+ sanityinc/last-compilation-buffer
+ (buffer-live-p (get-buffer sanityinc/last-compilation-buffer)))
+ (with-current-buffer sanityinc/last-compilation-buffer
+ (funcall orig edit-command))
+ (funcall orig edit-command)))
+ (advice-add 'recompile :around 'sanityinc/find-prev-compilation))
+
+(global-set-key [f6] 'recompile)
+
+
+(defun sanityinc/shell-command-in-view-mode (start end command &optional output-buffer replace &rest other-args)
+ "Put \"*Shell Command Output*\" buffers into view-mode."
+ (unless (or output-buffer replace)
+ (with-current-buffer "*Shell Command Output*"
+ (view-mode 1))))
+(advice-add 'shell-command-on-region :after 'sanityinc/shell-command-in-view-mode)
+
+
+(with-eval-after-load 'compile
+ (require 'ansi-color)
+ (defun sanityinc/colourise-compilation-buffer ()
+ (when (eq major-mode 'compilation-mode)
+ (ansi-color-apply-on-region compilation-filter-start (point-max))))
+ (add-hook 'compilation-filter-hook 'sanityinc/colourise-compilation-buffer))
+
+
+(provide 'init-compile)
+;;; init-compile.el ends here
--- /dev/null
+;;; init-editing-utils.el --- Day-to-day editing helpers -*- lexical-binding: t -*-
+;;; Commentary:
+;;; Code:
+
+(require-package 'unfill)
+
+;(when (fboundp 'electric-pair-mode) (add-hook 'after-init-hook 'electric-pair-mode))
+(add-hook 'after-init-hook 'electric-indent-mode)
+
+(maybe-require-package 'list-unicode-display)
+
+\f
+;;; Some basic preferences
+
+(setq-default
+ blink-cursor-interval 0.4
+ bookmark-default-file (locate-user-emacs-file ".bookmarks.el")
+ buffers-menu-max-size 30
+ case-fold-search t
+ column-number-mode t
+ ediff-split-window-function 'split-window-horizontally
+ ediff-window-setup-function 'ediff-setup-windows-plain
+ indent-tabs-mode nil
+ create-lockfiles nil
+ auto-save-default nil
+ make-backup-files nil
+ mouse-yank-at-point t
+ save-interprogram-paste-before-kill t
+ scroll-preserve-screen-position 'always
+ set-mark-command-repeat-pop t
+ tooltip-delay 1.5
+ truncate-lines nil
+ truncate-partial-width-windows nil)
+
+(add-hook 'after-init-hook 'delete-selection-mode)
+
+(add-hook 'after-init-hook 'global-auto-revert-mode)
+(setq global-auto-revert-non-file-buffers t
+ auto-revert-verbose nil)
+(with-eval-after-load 'autorevert
+ (diminish 'auto-revert-mode))
+
+(add-hook 'after-init-hook 'transient-mark-mode)
+
+
+\f
+;; Huge files
+
+(when (fboundp 'so-long-enable)
+ (add-hook 'after-init-hook 'so-long-enable))
+
+(require-package 'vlf)
+
+(defun ffap-vlf ()
+ "Find file at point with VLF."
+ (interactive)
+ (let ((file (ffap-file-at-point)))
+ (unless (file-exists-p file)
+ (error "File does not exist: %s" file))
+ (vlf file)))
+
+\f
+;;; A simple visible bell which works in all terminal types
+(require-package 'mode-line-bell)
+(add-hook 'after-init-hook 'mode-line-bell-mode)
+
+\f
+
+(when (maybe-require-package 'beacon)
+ (setq-default beacon-lighter "")
+ (setq-default beacon-size 20)
+ (add-hook 'after-init-hook 'beacon-mode))
+
+
+\f
+;;; Newline behaviour
+
+(global-set-key (kbd "RET") 'newline-and-indent)
+(defun sanityinc/newline-at-end-of-line ()
+ "Move to end of line, enter a newline, and reindent."
+ (interactive)
+ (move-end-of-line 1)
+ (newline-and-indent))
+
+(global-set-key (kbd "S-<return>") 'sanityinc/newline-at-end-of-line)
+
+\f
+
+(with-eval-after-load 'subword
+ (diminish 'subword-mode))
+
+\f
+
+(when (fboundp 'display-line-numbers-mode)
+ (setq-default display-line-numbers-width 3)
+ (add-hook 'prog-mode-hook 'display-line-numbers-mode))
+
+\f
+
+(when (boundp 'display-fill-column-indicator)
+ (setq-default indicate-buffer-boundaries 'left)
+ (setq-default display-fill-column-indicator-character ?\u254e)
+ (add-hook 'prog-mode-hook 'display-fill-column-indicator-mode))
+
+\f
+
+(when (require-package 'rainbow-delimiters)
+ (add-hook 'prog-mode-hook 'rainbow-delimiters-mode))
+
+\f
+
+(when (require-package 'expand-region)
+ (global-set-key (kbd "C-=") 'er/expand-region))
+
+\f
+(when (maybe-require-package 'symbol-overlay)
+ (dolist (hook '(prog-mode-hook html-mode-hook yaml-mode-hook conf-mode-hook))
+ (add-hook hook 'symbol-overlay-mode))
+ (with-eval-after-load 'symbol-overlay
+ (diminish 'symbol-overlay-mode)
+ (define-key symbol-overlay-mode-map (kbd "M-i") 'symbol-overlay-put)
+ (define-key symbol-overlay-mode-map (kbd "M-I") 'symbol-overlay-remove-all)
+ (define-key symbol-overlay-mode-map (kbd "M-n") 'symbol-overlay-jump-next)
+ (define-key symbol-overlay-mode-map (kbd "M-p") 'symbol-overlay-jump-prev)))
+
+\f
+;;; Zap *up* to char is a handy pair for zap-to-char
+(global-set-key (kbd "M-Z") 'zap-up-to-char)
+
+
+\f
+(require-package 'browse-kill-ring)
+(setq browse-kill-ring-separator "\f")
+(global-set-key (kbd "M-Y") 'browse-kill-ring)
+(with-eval-after-load 'browse-kill-ring
+ (define-key browse-kill-ring-mode-map (kbd "C-g") 'browse-kill-ring-quit)
+ (define-key browse-kill-ring-mode-map (kbd "M-n") 'browse-kill-ring-forward)
+ (define-key browse-kill-ring-mode-map (kbd "M-p") 'browse-kill-ring-previous))
+(with-eval-after-load 'page-break-lines
+ (add-to-list 'page-break-lines-modes 'browse-kill-ring-mode))
+
+
+;; Don't disable narrowing commands
+(put 'narrow-to-region 'disabled nil)
+(put 'narrow-to-page 'disabled nil)
+(put 'narrow-to-defun 'disabled nil)
+;; Don't disable case-change functions
+(put 'upcase-region 'disabled nil)
+(put 'downcase-region 'disabled nil)
+
+
+;; Show matching parens
+(add-hook 'after-init-hook 'show-paren-mode)
+
+
+\f
+;;; Handy key bindings
+
+(global-set-key (kbd "C-.") 'set-mark-command)
+(global-set-key (kbd "C-x C-.") 'pop-global-mark)
+
+(when (maybe-require-package 'avy)
+ (global-set-key (kbd "C-:") 'avy-goto-char-timer)
+ (global-set-key (kbd "C-'") 'avy-goto-char-2))
+
+(maybe-require-package 'iedit)
+
+(require-package 'multiple-cursors)
+;; multiple-cursors
+(global-set-key (kbd "C-<") 'mc/mark-previous-like-this)
+(global-set-key (kbd "C->") 'mc/mark-next-like-this)
+(global-set-key (kbd "C-c C-<") 'mc/mark-all-like-this)
+
+;; Train myself to use M-f and M-b instead
+(global-unset-key [M-left])
+(global-unset-key [M-right])
+
+(defun kill-back-to-indentation ()
+ "Kill from point back to the first non-whitespace character on the line."
+ (interactive)
+ (let ((prev-pos (point)))
+ (back-to-indentation)
+ (kill-region (point) prev-pos)))
+
+(global-set-key (kbd "C-M-<backspace>") 'kill-back-to-indentation)
+
+
+\f
+;;; Page break lines
+
+(when (maybe-require-package 'page-break-lines)
+ (add-hook 'after-init-hook 'global-page-break-lines-mode)
+ (with-eval-after-load 'page-break-lines
+ (diminish 'page-break-lines-mode)))
+
+
+\f
+;; Shift lines up and down with M-up and M-down. When paredit is enabled,
+;; it will use those keybindings. For this reason, you might prefer to
+;; use M-S-up and M-S-down, which will work even in lisp modes.
+
+(require-package 'move-dup)
+(global-set-key [M-up] 'move-dup-move-lines-up)
+(global-set-key [M-down] 'move-dup-move-lines-down)
+(global-set-key [M-S-up] 'move-dup-move-lines-up)
+(global-set-key [M-S-down] 'move-dup-move-lines-down)
+
+(global-set-key (kbd "C-c d") 'move-dup-duplicate-down)
+(global-set-key (kbd "C-c u") 'move-dup-duplicate-up)
+
+\f
+;;; Fix backward-up-list to understand quotes, see http://bit.ly/h7mdIL
+
+(defun sanityinc/backward-up-sexp (arg)
+ "Jump up to the start of the ARG'th enclosing sexp."
+ (interactive "p")
+ (let ((ppss (syntax-ppss)))
+ (cond ((elt ppss 3)
+ (goto-char (elt ppss 8))
+ (sanityinc/backward-up-sexp (1- arg)))
+ ((backward-up-list arg)))))
+
+(global-set-key [remap backward-up-list] 'sanityinc/backward-up-sexp) ; C-M-u, C-M-up
+
+
+\f
+;;; Cut/copy the current line if no region is active
+(require-package 'whole-line-or-region)
+(add-hook 'after-init-hook 'whole-line-or-region-global-mode)
+(with-eval-after-load 'whole-line-or-region
+ (diminish 'whole-line-or-region-local-mode))
+
+\f
+
+(defun sanityinc/open-line-with-reindent (n)
+ "A version of `open-line' which reindents the start and end positions.
+If there is a fill prefix and/or a `left-margin', insert them
+on the new line if the line would have been blank.
+With arg N, insert N newlines."
+ (interactive "*p")
+ (let* ((do-fill-prefix (and fill-prefix (bolp)))
+ (do-left-margin (and (bolp) (> (current-left-margin) 0)))
+ (loc (point-marker))
+ ;; Don't expand an abbrev before point.
+ (abbrev-mode nil))
+ (delete-horizontal-space t)
+ (newline n)
+ (indent-according-to-mode)
+ (when (eolp)
+ (delete-horizontal-space t))
+ (goto-char loc)
+ (while (> n 0)
+ (cond ((bolp)
+ (if do-left-margin (indent-to (current-left-margin)))
+ (if do-fill-prefix (insert-and-inherit fill-prefix))))
+ (forward-line 1)
+ (setq n (1- n)))
+ (goto-char loc)
+ (end-of-line)
+ (indent-according-to-mode)))
+
+(global-set-key (kbd "C-o") 'sanityinc/open-line-with-reindent)
+
+
+\f
+;; M-^ is inconvenient, so also bind M-j
+(global-set-key (kbd "M-j") 'join-line)
+
+\f
+;; Random line sorting
+(defun sanityinc/sort-lines-random (beg end)
+ "Sort lines in region from BEG to END randomly."
+ (interactive "r")
+ (save-excursion
+ (save-restriction
+ (narrow-to-region beg end)
+ (goto-char (point-min))
+ (let ;; To make `end-of-line' and etc. to ignore fields.
+ ((inhibit-field-text-motion t))
+ (sort-subr nil 'forward-line 'end-of-line nil nil
+ (lambda (s1 s2) (eq (random 2) 0)))))))
+
+\f
+
+(require-package 'highlight-escape-sequences)
+(add-hook 'after-init-hook 'hes-mode)
+
+\f
+(require-package 'which-key)
+(add-hook 'after-init-hook 'which-key-mode)
+(setq-default which-key-idle-delay 1.5)
+(with-eval-after-load 'which-key
+ (diminish 'which-key-mode))
+
+\f
+(defun sanityinc/disable-features-during-macro-call (orig &rest args)
+ "When running a macro, disable features that might be expensive.
+ORIG is the advised function, which is called with its ARGS."
+ (let (post-command-hook
+ font-lock-mode
+ (tab-always-indent (or (eq 'complete tab-always-indent) tab-always-indent)))
+ (apply orig args)))
+
+(advice-add 'kmacro-call-macro :around 'sanityinc/disable-features-during-macro-call)
+
+
+(provide 'init-editing-utils)
+;;; init-editing-utils.el ends here
--- /dev/null
+;;; init-elpa.el --- Settings and helpers for package.el -*- lexical-binding: t -*-
+;;; Commentary:
+;;; Code:
+
+(require 'package)
+(require 'cl-lib)
+
+
+\f
+;;; On-demand installation of packages
+
+(defun require-package (package &optional min-version no-refresh)
+ "Install given PACKAGE, optionally requiring MIN-VERSION.
+If NO-REFRESH is non-nil, the available package lists will not be
+re-downloaded in order to locate PACKAGE."
+ (or (package-installed-p package min-version)
+ (let* ((known (cdr (assoc package package-archive-contents)))
+ (best (car (sort known (lambda (a b)
+ (version-list-<= (package-desc-version b)
+ (package-desc-version a)))))))
+ (if (and best (version-list-<= min-version (package-desc-version best)))
+ (package-install best)
+ (if no-refresh
+ (error "No version of %s >= %S is available" package min-version)
+ (package-refresh-contents)
+ (require-package package min-version t)))
+ (package-installed-p package min-version))))
+
+(defun maybe-require-package (package &optional min-version no-refresh)
+ "Try to install PACKAGE, and return non-nil if successful.
+In the event of failure, return nil and print a warning message.
+Optionally require MIN-VERSION. If NO-REFRESH is non-nil, the
+available package lists will not be re-downloaded in order to
+locate PACKAGE."
+ (condition-case err
+ (require-package package min-version no-refresh)
+ (error
+ (message "Couldn't install optional package `%s': %S" package err)
+ nil)))
+
+\f
+;;; Fire up package.el
+
+(setq package-enable-at-startup nil)
+(package-initialize)
+
+\f
+;; package.el updates the saved version of package-selected-packages correctly only
+;; after custom-file has been loaded, which is a bug. We work around this by adding
+;; the required packages to package-selected-packages after startup is complete.
+
+(defvar sanityinc/required-packages nil)
+
+(defun sanityinc/note-selected-package (oldfun package &rest args)
+ "If OLDFUN reports PACKAGE was successfully installed, note that fact.
+The package name is noted by adding it to
+`sanityinc/required-packages'. This function is used as an
+advice for `require-package', to which ARGS are passed."
+ (let ((available (apply oldfun package args)))
+ (prog1
+ available
+ (when available
+ (add-to-list 'sanityinc/required-packages package)))))
+
+(advice-add 'require-package :around 'sanityinc/note-selected-package)
+
+(when (fboundp 'package--save-selected-packages)
+ (require-package 'seq)
+ (add-hook 'after-init-hook
+ (lambda ()
+ (package--save-selected-packages
+ (seq-uniq (append sanityinc/required-packages package-selected-packages))))))
+
+\f
+(require-package 'fullframe)
+(fullframe list-packages quit-window)
+
+\f
+(let ((package-check-signature nil))
+ (require-package 'gnu-elpa-keyring-update))
+
+\f
+(defun sanityinc/set-tabulated-list-column-width (col-name width)
+ "Set any column with name COL-NAME to the given WIDTH."
+ (when (> width (length col-name))
+ (cl-loop for column across tabulated-list-format
+ when (string= col-name (car column))
+ do (setf (elt column 1) width))))
+
+(defun sanityinc/maybe-widen-package-menu-columns ()
+ "Widen some columns of the package menu table to avoid truncation."
+ (when (boundp 'tabulated-list-format)
+ (sanityinc/set-tabulated-list-column-width "Version" 13)
+ (let ((longest-archive-name (apply 'max (mapcar 'length (mapcar 'car package-archives)))))
+ (sanityinc/set-tabulated-list-column-width "Archive" longest-archive-name))))
+
+(add-hook 'package-menu-mode-hook 'sanityinc/maybe-widen-package-menu-columns)
+
+(provide 'init-elpa)
+;;; init-elpa.el ends here
--- /dev/null
+;;; init-exec-path.el --- Set up exec-path to help Emacs find programs -*- lexical-binding: t -*-
+;;; Commentary:
+;;; Code:
+
+(require-package 'exec-path-from-shell)
+
+(with-eval-after-load 'exec-path-from-shell
+ (dolist (var '("SSH_AUTH_SOCK" "SSH_AGENT_PID" "GPG_AGENT_INFO" "LANG" "LC_CTYPE" "NIX_SSL_CERT_FILE" "NIX_PATH"))
+ (add-to-list 'exec-path-from-shell-variables var)))
+
+
+(when (or (memq window-system '(mac ns x))
+ (unless (memq system-type '(ms-dos windows-nt))
+ (daemonp)))
+ (exec-path-from-shell-initialize))
+
+(provide 'init-exec-path)
+;;; init-exec-path.el ends here
--- /dev/null
+;;; init-git.el --- Git SCM support -*- lexical-binding: t -*-
+;;; Commentary:
+
+;; See also init-github.el.
+
+;;; Code:
+
+;; TODO: link commits from vc-log to magit-show-commit
+;; TODO: smerge-mode
+(require-package 'git-blamed)
+(require-package 'gitignore-mode)
+(require-package 'gitconfig-mode)
+(when (maybe-require-package 'git-timemachine)
+ (global-set-key (kbd "C-x v t") 'git-timemachine-toggle))
+
+
+
+(when (maybe-require-package 'magit)
+ (setq-default magit-diff-refine-hunk t)
+
+ ;; Hint: customize `magit-repository-directories' so that you can use C-u M-F12 to
+ ;; quickly open magit on any one of your projects.
+ (global-set-key [(meta f12)] 'magit-status)
+ (global-set-key (kbd "C-x g") 'magit-status)
+ (global-set-key (kbd "C-x M-g") 'magit-dispatch)
+
+ (defun sanityinc/magit-or-vc-log-file (&optional prompt)
+ (interactive "P")
+ (if (and (buffer-file-name)
+ (eq 'Git (vc-backend (buffer-file-name))))
+ (if prompt
+ (magit-log-buffer-file-popup)
+ (magit-log-buffer-file t))
+ (vc-print-log)))
+
+ (with-eval-after-load 'vc
+ (define-key vc-prefix-map (kbd "l") 'sanityinc/magit-or-vc-log-file)))
+
+
+(with-eval-after-load 'magit
+ (define-key magit-status-mode-map (kbd "C-M-<up>") 'magit-section-up))
+
+
+(maybe-require-package 'magit-todos)
+
+(require-package 'fullframe)
+(with-eval-after-load 'magit
+ (fullframe magit-status magit-mode-quit-window))
+
+(when (maybe-require-package 'git-commit)
+ (add-hook 'git-commit-mode-hook 'goto-address-mode))
+
+\f
+(when *is-a-mac*
+ (with-eval-after-load 'magit
+ (add-hook 'magit-mode-hook (lambda () (local-unset-key [(meta h)])))))
+
+
+\f
+;; Convenient binding for vc-git-grep
+(with-eval-after-load 'vc
+ (define-key vc-prefix-map (kbd "f") 'vc-git-grep))
+
+
+\f
+;;; git-svn support
+
+;; (when (maybe-require-package 'magit-svn)
+;; (require-package 'magit-svn)
+;; (autoload 'magit-svn-enabled "magit-svn")
+;; (defun sanityinc/maybe-enable-magit-svn-mode ()
+;; (when (magit-svn-enabled)
+;; (magit-svn-mode)))
+;; (add-hook 'magit-status-mode-hook #'sanityinc/maybe-enable-magit-svn-mode))
+
+(with-eval-after-load 'compile
+ (dolist (defn (list '(git-svn-updated "^\t[A-Z]\t\\(.*\\)$" 1 nil nil 0 1)
+ '(git-svn-needs-update "^\\(.*\\): needs update$" 1 nil nil 2 1)))
+ (add-to-list 'compilation-error-regexp-alist-alist defn)
+ (add-to-list 'compilation-error-regexp-alist (car defn))))
+
+(defvar git-svn--available-commands nil "Cached list of git svn subcommands")
+(defun git-svn--available-commands ()
+ (or git-svn--available-commands
+ (setq git-svn--available-commands
+ (sanityinc/string-all-matches
+ "^ \\([a-z\\-]+\\) +"
+ (shell-command-to-string "git svn help") 1))))
+
+(autoload 'vc-git-root "vc-git")
+
+(defun git-svn (dir command)
+ "Run a git svn subcommand in DIR."
+ (interactive (list (read-directory-name "Directory: ")
+ (completing-read "git-svn command: " (git-svn--available-commands) nil t nil nil (git-svn--available-commands))))
+ (let* ((default-directory (vc-git-root dir))
+ (compilation-buffer-name-function (lambda (major-mode-name) "*git-svn*")))
+ (compile (concat "git svn " command))))
+
+
+(provide 'init-git)
+;;; init-git.el ends here
--- /dev/null
+;;; init-github.el --- Github integration -*- lexical-binding: t -*-
+;;; Commentary:
+;;; Code:
+
+(require 'init-git)
+
+(maybe-require-package 'yagist)
+(require-package 'bug-reference-github)
+(add-hook 'prog-mode-hook 'bug-reference-prog-mode)
+
+(maybe-require-package 'github-clone)
+(maybe-require-package 'forge)
+(maybe-require-package 'github-review)
+
+(provide 'init-github)
+;;; init-github.el ends here
--- /dev/null
+;;; init-go.el --- Go mode settings -*- lexical-binding: t -*-
+;;; Commentary:
+;;; Code:
+
+(require 'go-mode)
+
+(add-hook 'go-mode-hook (lambda () (local-set-key (kbd "M-.") #'godef-jump)))
+(add-hook 'before-save-hook #'gofmt-before-save)
+(add-hook 'go-mode-hook #'flycheck-golangci-lint-setup)
+(setq flycheck-golangci-lint-config "/Users/eshelyaron/checkouts/dockerfile-normalizer/.golangci.yml")
+
+(provide 'init-go)
+;;; init-go.el ends here
--- /dev/null
+;;; init-grep.el --- Settings for grep and grep-like tools -*- lexical-binding: t -*-
+;;; Commentary:
+;;; Code:
+
+(setq-default grep-highlight-matches t
+ grep-scroll-output t)
+
+(when *is-a-mac*
+ (setq-default locate-command "mdfind"))
+
+(require-package 'wgrep)
+(with-eval-after-load 'grep
+ (dolist (key (list (kbd "C-c C-q") (kbd "w")))
+ (define-key grep-mode-map key 'wgrep-change-to-wgrep-mode)))
+
+(when (and (executable-find "ag")
+ (maybe-require-package 'ag))
+ (require-package 'wgrep-ag)
+ (setq-default ag-highlight-search t)
+ (global-set-key (kbd "C-M-?") 'ag-project))
+
+(when (and (executable-find "rg")
+ (maybe-require-package 'rg))
+ (global-set-key (kbd "C-M-?") 'rg-project))
+
+
+(provide 'init-grep)
+;;; init-grep.el ends here
--- /dev/null
+;;; init-gui-frames.el --- Behaviour specific to non-TTY frames -*- lexical-binding: t -*-
+;;; Commentary:
+;;; Code:
+
+\f
+;; Stop C-z from minimizing windows under OS X
+
+(defun sanityinc/maybe-suspend-frame ()
+ (interactive)
+ (unless (and *is-a-mac* window-system)
+ (suspend-frame)))
+
+(global-set-key (kbd "C-z") 'sanityinc/maybe-suspend-frame)
+
+
+\f
+;; Suppress GUI features
+
+(setq use-file-dialog nil)
+(setq use-dialog-box nil)
+(setq inhibit-startup-screen t)
+
+
+\f
+;; Window size and features
+
+(setq-default
+ window-resize-pixelwise t
+ frame-resize-pixelwise t)
+
+(when (fboundp 'tool-bar-mode)
+ (tool-bar-mode -1))
+(when (fboundp 'set-scroll-bar-mode)
+ (set-scroll-bar-mode nil))
+
+(menu-bar-mode -1)
+
+(let ((no-border '(internal-border-width . 0)))
+ (add-to-list 'default-frame-alist no-border)
+ (add-to-list 'initial-frame-alist no-border))
+
+(defun sanityinc/adjust-opacity (frame incr)
+ "Adjust the background opacity of FRAME by increment INCR."
+ (unless (display-graphic-p frame)
+ (error "Cannot adjust opacity of this frame"))
+ (let* ((oldalpha (or (frame-parameter frame 'alpha) 100))
+ ;; The 'alpha frame param became a pair at some point in
+ ;; emacs 24.x, e.g. (100 100)
+ (oldalpha (if (listp oldalpha) (car oldalpha) oldalpha))
+ (newalpha (+ incr oldalpha)))
+ (when (and (<= frame-alpha-lower-limit newalpha) (>= 100 newalpha))
+ (modify-frame-parameters frame (list (cons 'alpha newalpha))))))
+
+(when (and *is-a-mac* (fboundp 'toggle-frame-fullscreen))
+ ;; Command-Option-f to toggle fullscreen mode
+ ;; Hint: Customize `ns-use-native-fullscreen'
+ (global-set-key (kbd "C-s-f") 'toggle-frame-fullscreen))
+
+;; TODO: use seethru package instead?
+(global-set-key (kbd "M-C-8") (lambda () (interactive) (sanityinc/adjust-opacity nil -2)))
+(global-set-key (kbd "M-C-9") (lambda () (interactive) (sanityinc/adjust-opacity nil 2)))
+(global-set-key (kbd "M-C-7") (lambda () (interactive) (modify-frame-parameters nil `((alpha . 100)))))
+
+
+(when *is-a-mac*
+ (when (maybe-require-package 'ns-auto-titlebar)
+ (ns-auto-titlebar-mode)))
+
+
+(setq frame-title-format
+ '((:eval (if (buffer-file-name)
+ (abbreviate-file-name (buffer-file-name))
+ "%b"))))
+
+;; Non-zero values for `line-spacing' can mess up ansi-term and co,
+;; so we zero it explicitly in those cases.
+(add-hook 'term-mode-hook
+ (lambda ()
+ (setq line-spacing 0)))
+
+\f
+;; Change global font size easily
+
+(require-package 'default-text-scale)
+(add-hook 'after-init-hook 'default-text-scale-mode)
+
+
+\f
+(require-package 'disable-mouse)
+
+
+(provide 'init-gui-frames)
+;;; init-gui-frames.el ends here
--- /dev/null
+;;; init-helpful.el --- Help with helpful -*- lexical-binding: t -*-
+;;; Commentary:
+;;; Code:
+
+(when (maybe-require-package 'helpful)
+ (global-set-key (kbd "C-h f") #'helpful-callable)
+ (global-set-key (kbd "C-h v") #'helpful-variable)
+ (global-set-key (kbd "C-h k") #'helpful-key))
+
+(provide 'init-helpful)
+;;; init-helpful.el ends here
--- /dev/null
+;;; init-hippie-expand.el --- Settings for hippie-expand -*- lexical-binding: t -*-
+;;; Commentary:
+;;; Code:
+
+(global-set-key (kbd "M-/") 'hippie-expand)
+
+(setq hippie-expand-try-functions-list
+ '(try-complete-file-name-partially
+ try-complete-file-name
+ try-expand-dabbrev
+ try-expand-dabbrev-all-buffers
+ try-expand-dabbrev-from-kill))
+
+(provide 'init-hippie-expand)
+;;; init-hippie-expand.el ends here
--- /dev/null
+;;; init-ialign.el --- Alignment with ialign -*- lexical-binding: t -*-
+;;; Commentary:
+;;; Code:
+
+(when (maybe-require-package 'ialign)
+ (global-set-key (kbd "C-x l") #'ialign))
+
+(provide 'init-ialign)
+;;; init-ialign.el ends here
--- /dev/null
+;;; init-ibuffer.el --- ibuffer settings -*- lexical-binding: t -*-
+;;; Commentary:
+
+;; TODO: enhance ibuffer-fontification-alist
+;; See http://www.reddit.com/r/emacs/comments/21fjpn/fontifying_buffer_list_for_emacs_243/
+
+;;; Code:
+
+(require-package 'fullframe)
+(with-eval-after-load 'ibuffer
+ (fullframe ibuffer ibuffer-quit))
+
+(require-package 'ibuffer-vc)
+
+(defun ibuffer-set-up-preferred-filters ()
+ (ibuffer-vc-set-filter-groups-by-vc-root)
+ (unless (eq ibuffer-sorting-mode 'filename/process)
+ (ibuffer-do-sort-by-filename/process)))
+
+(add-hook 'ibuffer-hook 'ibuffer-set-up-preferred-filters)
+
+(setq-default ibuffer-show-empty-filter-groups nil)
+
+
+(with-eval-after-load 'ibuffer
+ ;; Use human readable Size column instead of original one
+ (define-ibuffer-column size-h
+ (:name "Size" :inline t)
+ (file-size-human-readable (buffer-size))))
+
+
+;; Modify the default ibuffer-formats (toggle with `)
+(setq ibuffer-formats
+ '((mark modified read-only vc-status-mini " "
+ (name 22 22 :left :elide)
+ " "
+ (size-h 9 -1 :right)
+ " "
+ (mode 12 12 :left :elide)
+ " "
+ vc-relative-file)
+ (mark modified read-only vc-status-mini " "
+ (name 22 22 :left :elide)
+ " "
+ (size-h 9 -1 :right)
+ " "
+ (mode 14 14 :left :elide)
+ " "
+ (vc-status 12 12 :left)
+ " "
+ vc-relative-file)))
+
+(setq ibuffer-filter-group-name-face 'font-lock-doc-face)
+
+(global-set-key (kbd "C-x C-b") 'ibuffer)
+
+(provide 'init-ibuffer)
+;;; init-ibuffer.el ends here
--- /dev/null
+;;; init-idris2.el --- Idris2 mode settings -*- lexical-binding: t -*-
+;;; Commentary:
+;;; Code:
+
+(add-to-list 'load-path "~/.emacs.d/idris2-mode/")
+
+(require 'idris2-mode)
+
+(add-to-list 'auto-mode-alist '("\\.idr\\'" . idris2-mode))
+
+
+(provide 'init-idris2)
+;;; init-idris2.el ends here
--- /dev/null
+;;; init-isearch.el --- isearch settings -*- lexical-binding: t -*-
+;;; Commentary:
+;;; Code:
+
+;; Show number of matches while searching
+(when (maybe-require-package 'anzu)
+ (add-hook 'after-init-hook 'global-anzu-mode)
+ (setq anzu-mode-lighter "")
+ (global-set-key [remap query-replace-regexp] 'anzu-query-replace-regexp)
+ (global-set-key [remap query-replace] 'anzu-query-replace))
+
+(with-eval-after-load 'isearch
+ ;; DEL during isearch should edit the search string, not jump back to the previous result
+ (define-key isearch-mode-map [remap isearch-delete-char] 'isearch-del-char)
+
+ ;; Activate occur easily inside isearch
+ (when (fboundp 'isearch-occur)
+ ;; to match ivy conventions
+ (define-key isearch-mode-map (kbd "C-c C-o") 'isearch-occur)))
+
+;; Search back/forth for the symbol at point
+;; See http://www.emacswiki.org/emacs/SearchAtPoint
+(defun isearch-yank-symbol ()
+ "*Put symbol at current point into search string."
+ (interactive)
+ (let ((sym (thing-at-point 'symbol)))
+ (if sym
+ (progn
+ (setq isearch-regexp t
+ isearch-string (concat "\\_<" (regexp-quote sym) "\\_>")
+ isearch-message (mapconcat 'isearch-text-char-description isearch-string "")
+ isearch-yank-flag t))
+ (ding)))
+ (isearch-search-and-update))
+
+(define-key isearch-mode-map "\C-\M-w" 'isearch-yank-symbol)
+
+
+(defun sanityinc/isearch-exit-other-end ()
+ "Exit isearch, but at the other end of the search string.
+This is useful when followed by an immediate kill."
+ (interactive)
+ (isearch-exit)
+ (goto-char isearch-other-end))
+
+(define-key isearch-mode-map [(control return)] 'sanityinc/isearch-exit-other-end)
+
+
+(provide 'init-isearch)
+;;; init-isearch.el ends here
--- /dev/null
+;;; init-keyfreq.el --- Command frequency logging with keyfreq -*- lexical-binding: t -*-
+;;; Commentary:
+;;; Code:
+
+(when (maybe-require-package 'keyfreq)
+ (keyfreq-mode 1)
+ (keyfreq-autosave-mode 1)
+ (setq keyfreq-excluded-commands
+ '(self-insert-command
+ forward-char
+ backward-char
+ previous-line
+ next-line)))
+
+(provide 'init-keyfreq)
+;;; init-keyfreq.el ends here
--- /dev/null
+;;; init-minibuffer.el --- Config for minibuffer completion -*- lexical-binding: t; -*-
+;;; Commentary:
+;;; Code:
+
+
+(when (maybe-require-package 'vertico)
+ (add-hook 'after-init-hook 'vertico-mode)
+
+ (require-package 'orderless)
+ (with-eval-after-load 'vertico
+ (require 'orderless))
+
+ (defun sanityinc/use-orderless-in-minibuffer ()
+ (setq-local completion-styles '(substring orderless)))
+ (add-hook 'minibuffer-setup-hook 'sanityinc/use-orderless-in-minibuffer)
+
+ (when (maybe-require-package 'embark)
+ (with-eval-after-load 'vertico
+ (define-key vertico-map (kbd "C-c C-o") 'embark-export)
+ (define-key vertico-map (kbd "C-c C-c") 'embark-act)))
+
+ (when (maybe-require-package 'consult)
+ (defmacro sanityinc/no-consult-preview (&rest cmds)
+ `(with-eval-after-load 'consult
+ (consult-customize ,@cmds :preview-key (kbd "M-P"))))
+
+ (sanityinc/no-consult-preview
+ consult-ripgrep
+ consult-git-grep consult-grep
+ consult-bookmark consult-recent-file consult-xref
+ consult--source-bookmark)
+
+ (when (maybe-require-package 'projectile)
+ (setq-default consult-project-root-function 'projectile-project-root))
+
+ (when (and (executable-find "rg") (maybe-require-package 'affe))
+ (defun sanityinc/affe-grep-at-point (&optional dir initial)
+ (interactive (list prefix-arg (when-let ((s (symbol-at-point)))
+ (symbol-name s))))
+ (affe-grep dir initial))
+ (global-set-key (kbd "C-M-?") 'sanityinc/affe-grep-at-point)
+ (sanityinc/no-consult-preview sanityinc/affe-grep-at-point)
+ (with-eval-after-load 'affe (sanityinc/no-consult-preview affe-grep)))
+
+ (global-set-key [remap switch-to-buffer] 'consult-buffer)
+ (global-set-key [remap switch-to-buffer-other-window] 'consult-buffer-other-window)
+ (global-set-key [remap switch-to-buffer-other-frame] 'consult-buffer-other-frame)
+ (global-set-key [remap goto-line] 'consult-goto-line)
+
+
+
+ (when (maybe-require-package 'embark-consult)
+ (with-eval-after-load 'embark
+ (require 'embark-consult)
+ (add-hook 'embark-collect-mode-hook 'embark-consult-preview-minor-mode)))
+
+ (maybe-require-package 'consult-flycheck)))
+
+(when (maybe-require-package 'marginalia)
+ (add-hook 'after-init-hook 'marginalia-mode))
+
+
+(provide 'init-minibuffer)
+;;; init-minibuffer.el ends here
--- /dev/null
+;;; init-pdf.el --- PDF support -*- lexical-binding: t -*-
+;;; Commentary:
+
+;;; Code:
+
+(when (maybe-require-package 'pdf-tools)
+ (add-hook 'pdf-view-mode-hook 'pdf-tools-install))
+
+(provide 'init-pdf)
+;;; init-pdf.el ends here
--- /dev/null
+;;; init-projectile.el --- Use Projectile for navigation within projects -*- lexical-binding: t -*-
+;;; Commentary:
+;;; Code:
+
+(when (maybe-require-package 'projectile)
+ (add-hook 'after-init-hook 'projectile-mode)
+
+ ;; Shorter modeline
+ (setq-default projectile-mode-line-prefix " Proj")
+
+ (when (executable-find "rg")
+ (setq-default projectile-generic-command "rg --files --hidden"))
+
+ (with-eval-after-load 'projectile
+ (define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map))
+
+ (maybe-require-package 'ibuffer-projectile)
+ (maybe-require-package 'ggtags))
+
+
+(provide 'init-projectile)
+;;; init-projectile.el ends here
--- /dev/null
+;;; init-prolog.el --- Command frequency logging with keyfreq -*- lexical-binding: t -*-
+;;; Commentary:
+;;; Code:
+
+(add-to-list 'auto-mode-alist '("\\.pl\\'" . prolog-mode))
+(add-to-list 'auto-mode-alist '("\\.plt\\'" . prolog-mode))
+
+(maybe-require-package 'ediprolog)
+
+(when (maybe-require-package 'dap-mode)
+ (require 'dap-ui)
+ (require 'dap-swi-prolog)
+ (require 'vterm))
+
+(require 'showterm)
+
+(defun prolog-create-predicate-at-point ()
+ "foo"
+ (interactive)
+ (progn
+ (save-buffer)
+ (prolog-ensure-process)
+ (process-send-string "prolog" (concat "ie:create_predicate_at_point('" (buffer-file-name) "', " (number-to-string (point)) ").\n"))))
+
+(defun prolog-term-list-at-point ()
+ "bar"
+ (interactive)
+ (progn
+ (save-buffer)
+ (read (shell-command-to-string (concat "swipl -g \"ie:show_enclosing_ranges_at_point('" (buffer-file-name) "', " (number-to-string (point)) ")\" -t halt")))))
+
+(defun dap-swi-prolog-internal-terminal (command title debug-session)
+ "foo"
+ (term command))
+
+(global-set-key (kbd "C-c C-o") 'prolog-create-predicate-at-point)
+
+
+(defun dap-swi-prolog--populate-start-tcp-args (conf)
+ "Populate CONF with the required arguments."
+ (let ((conf (-> conf
+ (dap--put-if-absent :host "localhost")
+ (dap--put-if-absent :debugServer 3443)
+ (dap--put-if-absent :request "attach")
+ (dap--put-if-absent :name "SWI-Prolog Debug"))))
+ conf))
+
+(dap-register-debug-provider "swi-prolog-tcp" #'dap-swi-prolog--populate-start-tcp-args)
+
+;(require 'lsp)
+;
+;(lsp-register-client
+; (make-lsp-client :new-connection (lsp-stdio-connection (list "swipl"
+; "-g" "use_module(library(lsp_server))."
+; "-g" "lsp_server:main"
+; "-t" "halt"
+; "--" "stdio"))
+; :activation-fn (lsp-activate-on "prolog")
+; :priority -1
+; :server-id 'prolog-ls))
+;
+;(add-hook 'prolog-mode-hook #'lsp)
+
+
+(define-derived-mode dapscript-mode
+ prolog-mode "DAP script"
+ "Major mode for dapscript source files."
+ (flycheck-mode))
+
+(add-to-list 'auto-mode-alist '("\\.dapscript\\'" . dapscript-mode))
+(provide 'init-prolog)
+;;; init-prolog.el ends here
--- /dev/null
+;;; init-recentf.el --- Settings for tracking recent files -*- lexical-binding: t -*-
+;;; Commentary:
+;;; Code:
+
+(add-hook 'after-init-hook 'recentf-mode)
+(setq-default
+ recentf-max-saved-items 1000
+ recentf-exclude `("/tmp/" "/ssh:" ,(concat package-user-dir "/.*-autoloads\\.el\\'")))
+
+
+(provide 'init-recentf)
+;;; init-recentf.el ends here
--- /dev/null
+;;; init-site-lisp.el --- Support elisp manually installed in the site-lisp dir -*- lexical-binding: t -*-
+;;; Commentary:
+;;; Code:
+
+;;; Set load path
+
+(require 'cl-lib)
+
+(defun sanityinc/add-subdirs-to-load-path (parent-dir)
+ "Add every non-hidden subdir of PARENT-DIR to `load-path'."
+ (let ((default-directory parent-dir))
+ (setq load-path
+ (append
+ (cl-remove-if-not
+ #'file-directory-p
+ (directory-files (expand-file-name parent-dir) t "^[^\\.]"))
+ load-path))))
+
+;; Add both site-lisp and its immediate subdirs to `load-path'
+(let ((site-lisp-dir (expand-file-name "site-lisp/" user-emacs-directory)))
+ (push site-lisp-dir load-path)
+ (sanityinc/add-subdirs-to-load-path site-lisp-dir))
+
+\f;;; Utilities for grabbing upstream libs
+
+(defun site-lisp-dir-for (name)
+ (expand-file-name (format "site-lisp/%s" name) user-emacs-directory))
+
+(defun site-lisp-library-el-path (name)
+ (expand-file-name (format "%s.el" name) (site-lisp-dir-for name)))
+
+(defun download-site-lisp-module (name url)
+ (let ((dir (site-lisp-dir-for name)))
+ (message "Downloading %s from %s" name url)
+ (unless (file-directory-p dir)
+ (make-directory dir t))
+ (add-to-list 'load-path dir)
+ (let ((el-file (site-lisp-library-el-path name)))
+ (url-copy-file url el-file t nil)
+ el-file)))
+
+(defun ensure-lib-from-url (name url)
+ (unless (site-lisp-library-loadable-p name)
+ (byte-compile-file (download-site-lisp-module name url))))
+
+(defun site-lisp-library-loadable-p (name)
+ "Return whether or not the library `name' can be loaded from a
+source file under ~/.emacs.d/site-lisp/name/"
+ (let ((f (locate-library (symbol-name name))))
+ (and f (string-prefix-p (file-name-as-directory (site-lisp-dir-for name)) f))))
+
+
+(provide 'init-site-lisp)
+;;; init-site-lisp.el ends here
--- /dev/null
+;;; init-themes.el --- Defaults for themes -*- lexical-binding: t -*-
+;;; Commentary:
+;;; Code:
+
+;; Don't prompt to confirm theme safety. This avoids problems with
+;; first-time startup on Emacs > 26.3.
+(setq custom-safe-themes t)
+
+(when (maybe-require-package 'zenburn-theme)
+ ;; If you don't customize it, this is the theme you get.
+ (setq-default custom-enabled-themes '(zenburn)))
+
+;; Ensure that themes will be applied even if they have not been customized
+(defun reapply-themes ()
+ "Forcibly load the themes listed in `custom-enabled-themes'."
+ (dolist (theme custom-enabled-themes)
+ (unless (custom-theme-p theme)
+ (load-theme theme)))
+ (custom-set-variables `(custom-enabled-themes (quote ,custom-enabled-themes))))
+
+(add-hook 'after-init-hook 'reapply-themes)
+
+(provide 'init-themes)
+;;; init-themes.el ends here
--- /dev/null
+;;; init-utils.el --- Elisp helper functions and commands -*- lexical-binding: t -*-
+;;; Commentary:
+;;; Code:
+
+(define-obsolete-function-alias 'after-load 'with-eval-after-load "")
+
+\f
+;; Handier way to add modes to auto-mode-alist
+(defun add-auto-mode (mode &rest patterns)
+ "Add entries to `auto-mode-alist' to use `MODE' for all given file `PATTERNS'."
+ (dolist (pattern patterns)
+ (add-to-list 'auto-mode-alist (cons pattern mode))))
+
+;; Like diminish, but for major modes
+(defun sanityinc/set-major-mode-name (name)
+ "Override the major mode NAME in this buffer."
+ (setq-local mode-name name))
+
+(defun sanityinc/major-mode-lighter (mode name)
+ (add-hook (derived-mode-hook-name mode)
+ (apply-partially 'sanityinc/set-major-mode-name name)))
+
+\f
+;; String utilities missing from core emacs
+
+(defun sanityinc/string-all-matches (regex str &optional group)
+ "Find all matches for `REGEX' within `STR', returning the full match string or group `GROUP'."
+ (let ((result nil)
+ (pos 0)
+ (group (or group 0)))
+ (while (string-match regex str pos)
+ (push (match-string group str) result)
+ (setq pos (match-end group)))
+ result))
+
+
+\f
+;; Delete the current file
+
+(defun delete-this-file ()
+ "Delete the current file, and kill the buffer."
+ (interactive)
+ (unless (buffer-file-name)
+ (error "No file is currently being edited"))
+ (when (yes-or-no-p (format "Really delete '%s'?"
+ (file-name-nondirectory buffer-file-name)))
+ (delete-file (buffer-file-name))
+ (kill-this-buffer)))
+
+
+\f
+;; Rename the current file
+
+(defun rename-this-file-and-buffer (new-name)
+ "Renames both current buffer and file it's visiting to NEW-NAME."
+ (interactive "sNew name: ")
+ (let ((name (buffer-name))
+ (filename (buffer-file-name)))
+ (unless filename
+ (error "Buffer '%s' is not visiting a file!" name))
+ (progn
+ (when (file-exists-p filename)
+ (rename-file filename new-name 1))
+ (set-visited-file-name new-name)
+ (rename-buffer new-name))))
+
+\f
+;; Browse current HTML file
+
+(defun browse-current-file ()
+ "Open the current file as a URL using `browse-url'."
+ (interactive)
+ (let ((file-name (buffer-file-name)))
+ (if (and (fboundp 'tramp-tramp-file-p)
+ (tramp-tramp-file-p file-name))
+ (error "Cannot open tramp file")
+ (browse-url (concat "file://" file-name)))))
+
+
+(provide 'init-utils)
+;;; init-utils.el ends here
--- /dev/null
+;;; init-vc.el --- Version control support -*- lexical-binding: t -*-
+;;; Commentary:
+
+;; Most version control packages are configured separately: see
+;; init-git.el, for example.
+
+;;; Code:
+
+(when (maybe-require-package 'diff-hl)
+ (add-hook 'magit-post-refresh-hook 'diff-hl-magit-post-refresh)
+ (add-hook 'after-init-hook 'global-diff-hl-mode)
+
+ (with-eval-after-load 'diff-hl
+ (define-key diff-hl-mode-map
+ (kbd "<left-fringe> <mouse-1>")
+ 'diff-hl-diff-goto-hunk)))
+
+(maybe-require-package 'browse-at-remote)
+
+(provide 'init-vc)
+;;; init-vc.el ends here
--- /dev/null
+;;; init-web.el --- Browse with w3m -*- lexical-binding: t -*-
+;;; Commentary:
+;;; Code:
+
+(when (maybe-require-package 'w3m)
+ (setq browse-url-browser-function 'w3m-browse-url)
+ (autoload 'w3m-browse-url "w3m" "Ask a WWW browser to show a URL." t))
+
+(provide 'init-web)
+;;; init-web.el ends here
--- /dev/null
+;;; init-helpful.el --- Help with helpful -*- lexical-binding: t -*-
+;;; Commentary:
+;;; Code:
+
+(when (maybe-require-package 'helpful)
+ (global-set-key (kbd "C-h f") #'helpful-callable)
+ (global-set-key (kbd "C-h v") #'helpful-variable)
+ (global-set-key (kbd "C-h k") #'helpful-key))
+
+(provide 'init-helpful)
+;;; init-helpful.el ends here
--- /dev/null
+;;; init-whitespace.el --- Special handling for whitespace -*- lexical-binding: t -*-
+;;; Commentary:
+;;; Code:
+
+(setq-default show-trailing-whitespace nil)
+
+\f
+;;; Whitespace
+
+(defun sanityinc/show-trailing-whitespace ()
+ "Enable display of trailing whitespace in this buffer."
+ (setq-local show-trailing-whitespace t))
+
+(dolist (hook '(prog-mode-hook text-mode-hook conf-mode-hook))
+ (add-hook hook 'sanityinc/show-trailing-whitespace))
+
+
+(require-package 'whitespace-cleanup-mode)
+(add-hook 'after-init-hook 'global-whitespace-cleanup-mode)
+(with-eval-after-load 'whitespace-cleanup-mode
+ (diminish 'whitespace-cleanup-mode))
+
+(global-set-key [remap just-one-space] 'cycle-spacing)
+
+
+(provide 'init-whitespace)
+;;; init-whitespace.el ends here
--- /dev/null
+;;; init-windows.el --- Working with windows within frames -*- lexical-binding: t -*-
+;;; Commentary:
+
+;; This is not about the "Windows" OS, but rather Emacs's "windows"
+;; concept: these are the panels within an Emacs frame which contain
+;; buffers.
+
+;;; Code:
+
+;; Navigate window layouts with "C-c <left>" and "C-c <right>"
+
+(add-hook 'after-init-hook 'winner-mode)
+
+\f
+;; Make "C-x o" prompt for a target window when there are more than 2
+(require-package 'switch-window)
+(setq-default switch-window-shortcut-style 'alphabet)
+(setq-default switch-window-timeout nil)
+(global-set-key (kbd "C-x o") 'switch-window)
+
+
+\f
+;; When splitting window, show (other-buffer) in the new window
+
+(defun split-window-func-with-other-buffer (split-function)
+ (lambda (&optional arg)
+ "Split this window and switch to the new window unless ARG is provided."
+ (interactive "P")
+ (funcall split-function)
+ (let ((target-window (next-window)))
+ (set-window-buffer target-window (other-buffer))
+ (unless arg
+ (select-window target-window)))))
+
+(global-set-key (kbd "C-x 2") (split-window-func-with-other-buffer 'split-window-vertically))
+(global-set-key (kbd "C-x 3") (split-window-func-with-other-buffer 'split-window-horizontally))
+
+(defun sanityinc/toggle-delete-other-windows ()
+ "Delete other windows in frame if any, or restore previous window config."
+ (interactive)
+ (if (and winner-mode
+ (equal (selected-window) (next-window)))
+ (winner-undo)
+ (delete-other-windows)))
+
+(global-set-key (kbd "C-x 1") 'sanityinc/toggle-delete-other-windows)
+
+\f
+;; Rearrange split windows
+
+(defun split-window-horizontally-instead ()
+ "Kill any other windows and re-split such that the current window is on the top half of the frame."
+ (interactive)
+ (let ((other-buffer (and (next-window) (window-buffer (next-window)))))
+ (delete-other-windows)
+ (split-window-horizontally)
+ (when other-buffer
+ (set-window-buffer (next-window) other-buffer))))
+
+(defun split-window-vertically-instead ()
+ "Kill any other windows and re-split such that the current window is on the left half of the frame."
+ (interactive)
+ (let ((other-buffer (and (next-window) (window-buffer (next-window)))))
+ (delete-other-windows)
+ (split-window-vertically)
+ (when other-buffer
+ (set-window-buffer (next-window) other-buffer))))
+
+(global-set-key (kbd "C-x |") 'split-window-horizontally-instead)
+(global-set-key (kbd "C-x _") 'split-window-vertically-instead)
+
+\f
+;; Borrowed from http://postmomentum.ch/blog/201304/blog-on-emacs
+
+(defun sanityinc/split-window()
+ "Split the window to see the most recent buffer in the other window.
+Call a second time to restore the original window configuration."
+ (interactive)
+ (if (eq last-command 'sanityinc/split-window)
+ (progn
+ (jump-to-register :sanityinc/split-window)
+ (setq this-command 'sanityinc/unsplit-window))
+ (window-configuration-to-register :sanityinc/split-window)
+ (switch-to-buffer-other-window nil)))
+
+(global-set-key (kbd "<f7>") 'sanityinc/split-window)
+
+
+\f
+
+(defun sanityinc/toggle-current-window-dedication ()
+ "Toggle whether the current window is dedicated to its current buffer."
+ (interactive)
+ (let* ((window (selected-window))
+ (was-dedicated (window-dedicated-p window)))
+ (set-window-dedicated-p window (not was-dedicated))
+ (message "Window %sdedicated to %s"
+ (if was-dedicated "no longer " "")
+ (buffer-name))))
+
+(global-set-key (kbd "C-c <down>") 'sanityinc/toggle-current-window-dedication)
+
+
+\f
+
+(unless (memq window-system '(nt w32))
+ (require-package 'windswap)
+ (add-hook 'after-init-hook (apply-partially 'windmove-default-keybindings 'control))
+ (add-hook 'after-init-hook (apply-partially 'windswap-default-keybindings 'shift 'control)))
+
+
+(provide 'init-windows)
+;;; init-windows.el ends here
--- /dev/null
+;;; init-yassnippet.el --- Snippets with yasnippet -*- lexical-binding: t -*-
+;;; Commentary:
+;;; Code:
+
+(require 'yasnippet)
+(add-hook 'prog-mode-hook 'yas-minor-mode)
+(add-hook 'text-mode-hook 'yas-minor-mode)
+(add-hook 'after-init-hook 'yas-global-mode)
+
+(provide 'init-yassnippet)
+;;; init-yassnippet.el ends here
--- /dev/null
+;;; profile-dotemacs.el --- Profile your Emacs init file
+
+;; Copyright (C) 2010, 2012 David Engster
+
+;; Author: David Engster <dengste@eml.cc>
+
+;; This file is NOT part of GNU Emacs.
+
+;; This program is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License
+;; as published by the Free Software Foundation; either version 2
+;; of the License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This is to easily profile your Emacs init file (or any other
+;; script-like Emacs Lisp file, for that matter).
+
+;; It will go over all sexp's (balanced expressions) in the file and
+;; run them through `benchmark-run'. It will then show the file with
+;; overlays applied in a way that let you easily find out which sexp's
+;; take the most time. Since time is relative, it's not the absolute
+;; value that counts but the percentage of the total running time.
+;;
+;; * All other sexp's with a percentage greater than
+;; `profile-dotemacs-low-percentage' will be preceded by a
+;; highlighted line, showing the results from `benchmark-run'.
+;; Also, the more 'reddish' the background of the sexp, the more
+;; time it needs.
+
+;; * All other sexp's will be grayed out to indicate that their
+;; running time is miniscule. You can still see the benchmark
+;; results in the minibuffer by hovering over the sexp with the
+;; mouse.
+
+;; You can only benchmark full sexp's, so if you wrapped large parts
+;; of your init file in some conditional clause, you'll have to remove
+;; that for getting finer granularity.
+
+;;; Usage:
+
+;; Start emacs as follows:
+;;
+;; emacs -Q -l <PATH>/profile-dotemacs.el -f profile-dotemacs
+;;
+;; with <PATH> being the path to where this file resides.
+
+;;; Caveats (thanks to Raffaele Ricciardi for reporting those):
+
+;; - The usual `--debug-init' for debugging your init file won't work
+;; with profile-dotemacs, so you'll have to call
+;; `toggle-debug-on-error', either on the commandline or at the
+;; beginning of your init file.
+;; - `load-file-name' is nil when the init file is being loaded
+;; by the profiler. This might matter if you perform the
+;; bulk of initializations in a different file.
+;; - Starting external shells like IELM or eshell in your init file
+;; might mess with overlay creation, so this must not be done.
+
+;;; Download:
+
+;; You can always get the latest version from
+;; http://randomsample.de/profile-dotemacs.el
+
+;;; Code:
+
+(require 'thingatpt)
+(require 'benchmark)
+
+;; User variables
+
+(defvar profile-dotemacs-file "~/.emacs.d/init.el"
+ "File to be profiled.")
+
+(defvar profile-dotemacs-low-percentage 3
+ "Percentage which should be considered low.
+All sexp's with a running time below this percentage will be
+grayed out.")
+
+(defface profile-dotemacs-time-face
+ '((((background dark)) (:background "OrangeRed1"))
+ (t (:background "red3")))
+ "Background color to indicate percentage of total time.")
+
+(defface profile-dotemacs-low-percentage-face
+ '((((background dark)) (:foreground "gray25"))
+ (t (:foreground "gray75")))
+ "Face for sexps below `profile-dotemacs-low-percentage'.")
+
+(defface profile-dotemacs-highlight-face
+ '((((background dark)) (:background "blue"))
+ (t (:background "yellow")))
+ "Highlight face for benchmark results.")
+
+;; Main function
+
+(defun profile-dotemacs ()
+ "Load `profile-dotemacs-file' and benchmark its sexps."
+ (interactive)
+ (with-current-buffer (find-file-noselect profile-dotemacs-file t)
+ (setq buffer-read-only t) ;; just to be sure
+ (goto-char (point-min))
+ (let (start end results)
+ (while
+ (< (point)
+ (setq end (progn
+ (forward-sexp 1)
+ (point))))
+ (forward-sexp -1)
+ (setq start (point))
+ (add-to-list
+ 'results
+ `(,start ,end
+ ,(benchmark-run
+ (eval (sexp-at-point)))))
+ (goto-char end))
+ (profile-dotemacs-show-results results)
+ (switch-to-buffer (current-buffer)))))
+
+;; Helper functions
+
+(defun profile-dotemacs-show-results (results)
+ "Show timings from RESULTS in current buffer."
+ (let ((totaltime (profile-dotemacs-totaltime results))
+ current percentage ov)
+ (while results
+ (let* ((current (pop results))
+ (ov (make-overlay (car current) (cadr current)))
+ (current (car (last current)))
+ (percentage (/ (+ (car current) (nth 2 current))
+ totaltime))
+ col benchstr lowface)
+ (setq col
+ (profile-dotemacs-percentage-color
+ percentage
+ (face-background 'default)
+ (face-background 'profile-dotemacs-time-face)))
+ (setq percentage (round (* 100 percentage)))
+ (setq benchstr (profile-dotemacs-make-benchstr current))
+ (overlay-put ov 'help-echo benchstr)
+ (if (and (numberp profile-dotemacs-low-percentage)
+ (< percentage profile-dotemacs-low-percentage))
+ (overlay-put ov 'face 'profile-dotemacs-low-percentage-face)
+ (overlay-put ov 'before-string
+ (propertize benchstr
+ 'face 'profile-dotemacs-highlight-face))
+ (overlay-put ov 'face
+ `(:background ,col)))))
+ (setq ov (make-overlay (1- (point-max)) (point-max)))
+ (overlay-put ov 'after-string
+ (propertize
+ (format "\n-----------------\nTotal time: %.2fs\n"
+ totaltime)
+ 'face 'profile-dotemacs-highlight-face))))
+
+(defun profile-dotemacs-totaltime (results)
+ "Calculate total time of RESULTS."
+ (let ((totaltime 0))
+ (mapc (lambda (x)
+ (let ((cur (car (last x))))
+ (setq totaltime (+ totaltime (car cur) (nth 2 cur)))))
+ results)
+ totaltime))
+
+(defun profile-dotemacs-percentage-color (percent col-begin col-end)
+ "Calculate color according to PERCENT between COL-BEGIN and COL-END."
+ (let* ((col1 (color-values col-begin))
+ (col2 (color-values col-end))
+ (col
+ (mapcar (lambda (c)
+ (round
+ (+ (* (- 1 percent) (nth c col1))
+ (* percent (nth c col2)))))
+ '(0 1 2))))
+ (format "RGB:%04x/%04x/%04x"
+ (car col)
+ (nth 1 col)
+ (nth 2 col))))
+
+(defun profile-dotemacs-make-benchstr (timings)
+ "Create descriptive benchmark string from TIMINGS."
+ (format
+ (concat
+ "<Percentage: %d ; "
+ "Time: %.2f ; "
+ "Number of GC: %d ; "
+ "Time for GC: %.2f>\n")
+ percentage
+ (car timings) (nth 1 timings) (nth 2 timings)))
+
+
+;; profile-dotemacs.el ends here
--- /dev/null
+;;; publish.el --- generate and publish my site -*- lexical-binding: t -*-
+
+;; Copyright (C) 2021-2022 Eshel Yaron
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'ox-publish)
+(require 'ox-html)
+(require 'htmlize)
+(require 'f)
+
+(setq org-export-with-section-numbers nil
+ org-export-with-toc nil)
+
+(setq org-html-html5-fancy t
+ org-html-doctype "html5")
+
+(setq org-html-head-include-default-style nil
+ org-html-head-include-scripts nil)
+
+(setq org-html-htmlize-output-type 'css)
+
+(setq org-publish-project-alist
+ `(("index"
+ :base-directory "~/checkouts/eshelyaron.com/org"
+ :base-extension "org"
+ :exclude ".*"
+ :include ("index.org")
+ :publishing-directory "/ssh:root@107.173.25.133:/var/www/html"
+ :publishing-function org-html-publish-to-html
+ :html-head "<link rel=\"stylesheet\" href=\"/style.css\" type=\"text/css\"/>"
+ :html-postamble ,(f-read-text "~/checkouts/eshelyaron.com/org/html_postamble.html"))
+ ("static"
+ :base-directory "~/checkouts/eshelyaron.com/org"
+ :base-extension "ico\\|css\\|jpg\\|gif\\|png\\|txt\\|pdf"
+ :recursive t
+ :publishing-directory "/ssh:root@107.173.25.133:/var/www/html"
+ :publishing-function org-publish-attachment)
+ ("eshelyaron.com" :components ("index" "static"))
+ ("index.local"
+ :base-directory "~/checkouts/eshelyaron.com/org"
+ :base-extension "org"
+ :exclude ".*"
+ :include ("index.org")
+ :publishing-directory "~/checkouts/eshelyaron.com/html"
+ :publishing-function org-html-publish-to-html
+ :html-head "<link rel=\"stylesheet\" href=\"/style.css\" type=\"text/css\"/>"
+ :html-postamble ,(f-read-text "~/checkouts/eshelyaron.com/org/html_postamble.html"))
+ ("static.local"
+ :base-directory "~/checkouts/eshelyaron.com/org"
+ :base-extension "ico\\|css\\|jpg\\|gif\\|png\\|txt\\|pdf"
+ :recursive t
+ :publishing-directory "~/checkouts/eshelyaron.com/html"
+ :publishing-function org-publish-attachment)
+ ("eshelyaron.local" :components ("index.local" "static.local"))))
+
+
+(provide 'publish)
+;;; publish.el ends here
--- /dev/null
+/.emacs.d/.bookmarks.el
+/.emacs.d/.cache/
+/.emacs.d/.dap-breakpoints
+/.emacs.d/.last-package-update-day
+/.emacs.d/.lsp-session-v1
+/.emacs.d/.org-id-locations
+/.emacs.d/auto-save-list/
+/.emacs.d/cache/
+/.emacs.d/dtache.db
+/.emacs.d/eln-cache/
+/.emacs.d/elpa/
+/.emacs.d/eshell/
+/.emacs.d/forge-database.sqlite
+/.emacs.d/network-security.data
+/.emacs.d/projectile-bookmarks.eld
+/.emacs.d/projects
+/.emacs.d/recentf
+/.emacs.d/request/
+/.emacs.d/snippets/
+/.emacs.d/tramp
+/.emacs.d/transient/
+/.emacs.d/url/
+/.emacs.d/var/
--- /dev/null
+[submodule ".emacs.d/checkouts/flymake-swi-prolog"]
+ path = .emacs.d/checkouts/flymake-swi-prolog
+ url = https://git.sr.ht/~eshel/flymake-swi-prolog