Startup related tasks/setup that might be used later on.
Setup the builtin emacs package manager.
(require 'package) (package-initialize)
This is out of place but to catch the gui elements early.
(tool-bar-mode -1) (scroll-bar-mode -1) (when (not (window-system)) (menu-bar-mode -1))
Add in standard package archive urls. Marmalade is gone as its ssl cert expired in 2018, so don't think its even worth using.
(add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/") t)
(add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/") t)
(add-to-list 'package-archives '("stable-melpa" . "https://stable.melpa.org/packages/") t)
(add-to-list 'package-archives '("gnu" . "https://elpa.gnu.org/packages/") t)
Duplicated from tangle.el just to make using org easier.
TODO: make this stuff work sanely in emacs org mode and via external tangling. Not tangled for now.
(defun tangle/yn (p) (if (bound-and-true-p p) "yes" "no")) (defun tangle/file (file p) (if (bound-and-true-p p) (concat "tmp/" file) "no"))
(defun my-minibuffer-setup-hook () (setq gc-cons-threshold most-positive-fixnum)) (defun my-minibuffer-exit-hook () (setq gc-cons-threshold 8000000)) (add-hook 'minibuffer-setup-hook #'my-minibuffer-setup-hook) (add-hook 'minibuffer-exit-hook #'my-minibuffer-exit-hook)
This configuration is using use-package extensively. Install it early so we can use it elsewhere.
First strip out any existing org load-path prior to package initialization.
(require 'cl) (setq load-path (remove-if (lambda (x) (string-match-p "org$" x)) load-path)) (setq load-path (remove-if (lambda (x) (string-match-p "org-" x)) load-path))
(unless (package-installed-p 'use-package)
(progn
(package-refresh-contents)
(package-install 'use-package)
(package-initialize)))
(require 'use-package)
(setq use-package-verbose t)
Then, before doing ANY package initialization, make use-package setup/use org from the package repos and pin it so that other packages can't muck that up.
(use-package org :ensure org-plus-contrib :pin org)
Make updating use-package installed package.el packages easy peasy.
(use-package auto-package-update :ensure t :defer t)
(defun string/ends-with (string suffix)
"Return t if STRING ends with SUFFIX."
(and (string-match (rx-to-string `(: ,suffix eos) t)
string)
t)
)
Not having to start emacs with –debug-init is useful.
(setq-default debug-on-error t)
Start up the emacs server if it isn't running.
(load "server") (unless (server-running-p) (server-start))
Sick of solarized, going back to good old black on white minimalism like paper.
TODO: Maybe get this to go dark automagically?
(use-package minimal-theme :ensure t :config (load-theme 'minimal-light t))
Make it easier to determine what os we're running on.
(defvar on-mswindows (string-match "windows" (symbol-name system-type)) "Am I running under windows?") (defvar on-osx (string-match "darwin" (symbol-name system-type)) "Am I running under osx?") (defvar on-linux (string-match "gnu/linux" (symbol-name system-type)) "Am I running under linux?")
Like the startup screen and the echo hooey.
(custom-set-variables '(inhibit-startup-screen t) '(inhibit-startup-message t) '(inhibit-startup-echo-area-message t) '(initial-scratch-message nil) )
Keep temporary stuff isolated from everyone else. It infects everything otherwise. As bad as the .DS_Store files on osx.
(custom-set-variables
'(temporary-file-directory "/tmp")
'(backup-directory-alist `((".*" . ,temporary-file-directory)))
'(auto-save-file-name-transforms `((".*" ,temporary-file-directory t)))
'(create-lockfiles nil)
'(make-backup-files nil)
'(auto-save-default nil)
'(backup-by-copying t)
'(auto-save-list-file-prefix temporary-file-directory)
'(backup-directory-alist `((".*" . ,temporary-file-directory)))
'(auto-save-file-name-transforms `((".*" ,temporary-file-directory t)))
)
Update files in open buffers as they're changed on disk, freaking annoying without this on.
(custom-set-variables '(global-auto-revert-mode t))
Use dired-x.
(add-hook 'dired-load-hook (function (lambda () (load "dired-x"))))
For those rare times I use it, make it a bit less derp on output.
(setq ediff-window-setup-function 'ediff-setup-windows-plain) (setq ediff-split-window-function 'split-window-horizontally)
Trailing whitespace is not normally useful. Remove it always on save in the before-save-hook.
(add-hook 'before-save-hook 'delete-trailing-whitespace)
Because its derp to have to chmod 755 stuff after I save. Honestly, do it for me kthxbai.
(add-hook 'after-save-hook 'executable-make-buffer-file-executable-if-script-p)
(put 'upcase-region 'disabled nil)
Line wrapping is useful. Enable it globally for a start.
Need word-wrap so kill line kills the line, not the displayed line.
(global-visual-line-mode t) (custom-set-variables '(word-wrap t))
So if we don't know, call it text-mode.
(custom-set-variables '(default-major-mode 'text-mode))
utf8 is the best. Default to it.
(use-package unicode-escape :init (set-language-environment "UTF-8") :ensure t)
(custom-set-variables '(locale-coding-system 'utf-8)) (set-terminal-coding-system 'utf-8) (set-keyboard-coding-system 'utf-8) (set-selection-coding-system 'utf-8) (prefer-coding-system 'utf-8)
If I selected text, delete the selection, I probably meant it emacs.
(delete-selection-mode 1)
80 char line columns not 72.
(custom-set-variables '(fill-column 80))
Double spacing after a line isn't needed. We aren't animals emacs, we have computers.
(set-default 'sentence-end-double-space nil)
Improve the performance of emacs with files that contain long lines. Disable left to right and right to left in the same buffer support. Until or if I learn a language that needs this I can deal with it then.
(setq-default bidi-paragraph-direction 'left-to-right)
Also disable this algorithm, which may unbalance ()'s in bidirectional language detection. But again as I don't use/speak/read them. Ok tradeoff.
(if (version<= "27.1" emacs-version)
((setq bidi-inhibit-bpa t)
(global-so-long-mode 1)))
Ref: https://200ok.ch/posts/2020-09-29_comprehensive_guide_on_handling_long_lines_in_emacs.html
Semi related to the above, make the sentence endings a bit more code-ish.
(custom-set-variables '(sentence-end "[.?!][]\"')]*\\($\\|\t\\| \\)[ \t\n]*") '(sentence-end-double-space nil) )
Two seems sensible, cause well, tabs are evil incarnate.
Lets use a tab width of 2 by default.
(custom-set-variables '(default-tab-width 2))
Customize whitespace mode to make tabs obvious as boxes, and to highlight lines over 80 characters in length.
(require 'whitespace)
(setq whitespace-style '(face tabs trailing))
(set-face-attribute 'whitespace-tab nil
:foreground "#2075c7"
:background "lightgrey")
(set-face-attribute 'whitespace-line nil
:foreground "#2075c7"
:background "lightgrey")
(add-hook 'prog-mode 'whitespace-mode)
(add-hook 'prog-mode 'hl-line-mode)
(add-hook 'prog-mode 'visual-line-mode)
I have no idea how to label these.
Highlight parens.
(show-paren-mode)
Typing out yes or no is stupid.
(fset 'yes-or-no-p 'y-or-n-p)
Disable the stupid prompt added in 23.2 that asks if you want to kill a buffer with a process attached. Yes, obviously, shut up and do it.
(setq kill-buffer-query-functions
(remq 'process-kill-buffer-query-function kill-buffer-query-functions))
TESTING tooltip mode
Puts all tooltips in the echo arear.
(tooltip-mode -1) (custom-set-variables '(tooltip-use-echo-area t))
TESTING redisplay
Have emacs not redraw the display before processing input events.
(custom-set-variables '(redisplay-dont-pause t))
On osx, don't ever display the gui dialog box. Taken from http://superuser.com/questions/125569/how-to-fix-emacs-popup-dialogs-on-mac-os-x
(when (and on-osx (window-system))
(defadvice yes-or-no-p (around prevent-dialog activate)
"Prevent yes-or-no-p from activating a dialog"
(let ((use-dialog-box nil))
ad-do-it))
(defadvice y-or-n-p (around prevent-dialog-yorn activate)
"Prevent y-or-n-p from activating a dialog"
(let ((use-dialog-box nil))
ad-do-it))
)
Command should be meta on cocoa emacs like the old carbon/macports version.
(when (and on-osx (window-system)) (custom-set-variables '(mac-command-key-is-meta t) '(mac-option-key-is-meta nil) '(mac-command-key-is-meta t) '(mac-command-modifier 'meta) '(mac-option-modifier 'none) ) )
Global key bindings.
(global-set-key (kbd "C-x ,") 'kill-whole-line) (global-set-key (kbd "C-x C-m") 'compile)
(when (and on-linux (window-system))
(progn
(setq interprogram-paste-function 'x-cut-buffer-or-selection-value)
(setq x-select-enable-clipboard t)
)
)
Trying something new here.
(setq default-frame-alist
(append (list
'(right-fringe . 0)
'(font . "Comic Code 14")
'(min-height . 1)
'(height . 42)
'(foreground-color . "#333333")
'(background-color . "#ffffff")
'(cursor-color . "black")
'(internal-border-width . 1)
'(tool-bar-lines . 0)
'(menu-bar-lines . 0))))
List of fonts in order of preference. Set preferred font list when we're in a gui emacs session.
TODO is this doesn't loop through the gui fonts right and set based on the alist order of the first matching font in macos.
(defvar my/gui-fonts
'(
"ComicCode"
"Comic Code"
"PragmataPro"
"Pragmata Pro" ;; Seems to register differently on osx than X
"Source Code Pro"
"Menlo"
"Monaco"
)
)
(with-no-warnings
(when window-system
(if (find-font (font-spec :name (car my/gui-fonts)))
(progn (set-frame-font (car my/gui-fonts))
(set-face-attribute 'default nil :height 180))
(progn (set-gui-font (cdr my/gui-fonts))))
)
)
Enable mouse mode for the console and use the mousewheel if possible.
(unless window-system
(require 'mouse)
(xterm-mouse-mode t)
(global-set-key [mouse-4] '(lambda ()
(interactive)
(scroll-down 1)))
(global-set-key [mouse-5] '(lambda ()
(interactive)
(scroll-up 1)))
(defun track-mouse (e))
)
All the packages I use.
If editorconfig is around use it.
(use-package editorconfig :ensure t :config (editorconfig-mode 1))
(use-package tramp
:defer 5
:custom
(tramp-default-method "ssh")
:config
(add-to-list 'tramp-default-proxies-alist '(".*" "\`root\'" "/ssh:%h:"))
)
Turns out that someone wrote this exact thing already. Yay get to drop my own crap.
(use-package exec-path-from-shell :ensure t :if (memq window-system '(mac ns)) :config (exec-path-from-shell-initialize) )
(use-package osx-clipboard :if (memq window-system '(mac ns)) :ensure t :config (osx-clipboard-mode +1))
Using some hacked together minimal mode line stuff now, spaceline too too much oomph with all the crap it did.
(defun my-flycheck-lighter (state)
"formats the mode-line fycheck error/warning/note junk"
(let* ((counts (flycheck-count-errors flycheck-current-errors))
(errorp (flycheck-has-current-errors-p state))
(err (or (cdr (assq state counts)) "?"))
(running (eq 'running flycheck-last-status-change)))
(if (or errorp running) (format "•%s" err))))
TODO: Use or ditch?
(use-package org-protocol-capture-html :after quelpa-use-package :quelpa (org-protocol-capture-html :repo "alphapapa/org-protocol-capture-html" :fetcher github))
(use-package quelpa-use-package
:ensure t)
(use-package s :ensure t)
(use-package mini-modeline
:ensure t
:after quelpa-use-package
:quelpa (mini-modeline :repo "kiennq/emacs-mini-modeline" :fetcher github)
:config
(mini-modeline-mode)
:custom
(mini-modeline-truncate-p nil)
(mini-modeline-echo-duration 5)
(mini-modeline-face-attr '(:background "white" :weight normal :box (:line-width 2 :color "#ffffff")))
(mini-modeline-display-gui-line nil)
(mini-modeline-r-format '((:eval
(when (and (bound-and-true-p flycheck-mode)
(or flycheck-current-errors
(eq 'running flycheck-last-status-change)))
(concat
" "
(cl-loop for state in '((error . "#FB4933")
(warning . "#FABD2F")
(info . "#83A598"))
as lighter = (my-flycheck-lighter (car state))
when lighter
concat (propertize
lighter
'face `(:foreground ,(cdr state))))
)))
"%e %b %c"
(:eval (if (use-region-p)
(if (eq (point) (region-beginning))
(format "%%l … %d" (line-number-at-pos (region-end)))
(format "%d … %%l" (line-number-at-pos (region-beginning))))
":%l")))))
(use-package yasnippet
:ensure t
:init
(setq yas-snippet-dirs
'("~/.emacs.d/snippets"
"~/.emacs.d/snippets-upstream"
))
:config
(yas/reload-all)
:hook ((prog-mode . yas-minor-mode)
(org-mode . yas-minor-mode))
)
Note that not all these functions are defined at package install time
(use-package semantic :ensure t :config (add-to-list 'semantic-default-submodes 'global-semantic-stickyfunc-mode) (custom-set-variables '(global-semantic-decoration-mode t) '(global-semantic-highlight-func-mode t) '(global-semantic-idle-scheduler-mode t) '(global-semantic-idle-local-symbol-highlight-mode t) ) :init (semantic-mode t))
(use-package expand-region
:ensure t
:bind ("C-]" . er/expand-region))
Switching to ivy mode+swiper
(use-package projectile
:ensure t
:init
(projectile-global-mode))
(use-package counsel
:ensure t
:bind (("C-x C-f" . counsel-find-file)
("C-c g" . counsel-git)
("C-c j" . counsel-git-grep)
("C-c k" . counsel-ag)
("C-x l" . counsel-locate)
("C-S-o" . counsel-rhythmbox)
("C-c C-r" . ivy-resume))
:custom
(counsel-find-file-at-point t))
(use-package swiper
:ensure t
:bind (("C-s" . swiper)
("M-x" . counsel-M-x))
:config
(ivy-mode 1)
:custom
(projectile-completion-system 'ivy)
(magit-completing-read-function 'ivy-completing-read)
(ivy-use-virtual-buffers t)
(ivy-height 10)
(ivy-count-format "(%d/%d) "))
Make git not ass to use. At least in emacs. magit is the best git interface… in the world.
(use-package magit
:ensure t
:commands (magit-init
magit-status
magit-diff
magit-commit)
:bind ("C-x m" . magit-status)
:custom
(magit-auto-revert-mode nil)
(magit-last-seen-setup-instructions "1.4.0")
:config
(defadvice magit-status (around magit-fullscreen activate)
(window-configuration-to-register :magit-fullscreen)
ad-do-it
(delete-other-windows))
(defadvice magit-quit-window (around magit-restore-screen activate)
ad-do-it
(jump-to-register :magit-fullscreen)))
And add TODO detection to the magit buffer. That way they get bubbled up to the top to look at.
(use-package magit-todos :ensure t :after magit :hook (magit-mode . magit-todos-mode))
Save workgroup layouts. Similar..ish to desktop-save.
(use-package workgroups2 :ensure t :custom (wg-session-file "~/.emacs.d/workgroups") (wg-prefix-key (kbd "C-c C-w")) (wg-mode-line-display-on nil) :init (workgroups-mode 1) )
Highlight matching ()'s []'s etc…
(use-package autopair :ensure t :custom (autopair-blink 'nil) )
Org-mode keybindings and settings, pretty sparse really.
Todo is to figure out what needs to happen for the capture templates and validate the agenda changes.
;; (defun org-roam-monolith-capture-date-file(path &optional extension)
;; (mkdir-base-path path)
;; (format "%s/%s%s" base (format-time-string "%Y-%m-%d:%H:%M:%S")
;; ))
;; (defun org-roam-monolith-base-path(path)
;; (expand-file-name (concat path (format-time-string "/%Y/%B"))))
;; (defun org-roam-monolith-mkdir-base-path(path)
;; (mkdir (base-path path) t))
;; (defun org-roam-monolith-file-extension(extension)
;; (if (eq extension nil) ""
;; (if (string-match-p "\\." extension)
;; extension
;; (concat "." extension))))
;; (defun org-roam-monolith-ref-url(url path)
;; (setq base (org-roam-monolith-base-path path))
;; ;; (setq file-string (format-time-string "%Y-%m-%d:%H:%M:%S"))
;; (setq file-string "test")
;; (org-roam-monolith-mkdir-base-path(base))
;; (setq file-prefix (format "%s/%s" base, file-string))
;; (setq title (org-web-tools--html-title url))
;; (setq )
;; (append-to-file
;; (format "#+TITLE: %s\n#+ROAM_KEY: %s\n\n Monolith archive [[%s][%s]]\n" title url
;; title url (mt/insert-url-as-org url))
;; nil
;; reffile)
;; (find-file-other-window reffile)
;; )
;; (defun mt/roam-ref-url()
;; (interactive)
;; (progn
;; (setq url (read-string "url: "))
;; (setq reffile (capture-date-file "~/src/org/ref/url"))
;; (append-to-file
;; (format "#+TITLE: %s\n#+ROAM_KEY: %s\n\n\n* Content\n%s"
;; (org-web-tools--html-title url) url (mt/insert-url-as-org url))
;; nil
;; reffile)
;; (find-file-other-window reffile)))
;; (defun mt/insert-url-as-org(url)
;; (org-web-tools--html-to-org-with-pandoc
;; (org-web-tools--get-url url)))
(defun capture-file-extension(extension)
(if (eq extension nil) ""
(if (string-match-p "\\." extension)
extension
(concat "." extension))))
(defun capture-date-file(path &optional extension)
(setq prefix (expand-file-name (concat path (format-time-string "/%Y/%B"))))
(mkdir prefix t)
(setq file-name (format-time-string "%Y-%m-%d:%H:%M:%S"))
(format "%s/%s%s" prefix file-name (capture-file-extension extension)))
(use-package org
:ensure org-plus-contrib
:pin org
:bind (("C-c a" . org-agenda)
("C-c b" . org-iswitchb)
("C-c c" . org-capture)
("C-c l" . org-store-link)
("C-c p" . org-latex-export-to-pdf))
:config
(add-to-list 'org-structure-template-alist '("el" . "#+BEGIN_SRC emacs-lisp\n?\n#+END_SRC"))
(add-to-list 'org-structure-template-alist '("hs" . "#+BEGIN_SRC haskell\n?\n#+END_SRC"))
(add-to-list 'org-structure-template-alist '("pl" . "#+BEGIN_SRC perl\n?\n#+END_SRC"))
(add-to-list 'org-structure-template-alist '("py" . "#+BEGIN_SRC python\n?\n#+END_SRC"))
(add-to-list 'org-structure-template-alist '("sh" . "#+BEGIN_SRC sh\n?\n#+END_SRC"))
(org-babel-do-load-languages
'org-babel-load-languages
(append org-babel-load-languages
'(
(C . t)
(ditaa . t)
(emacs-lisp . t)
(haskell . t)
(latex . t)
(perl . t)
(python . t)
(ruby . t)
(shell . t)
)))
:custom
(org-directory "~/src/org")
;; Don't sort-lines ^^^
(org-agenda-span 'fortnight)
(org-archive-directory "~/src/org/attic")
(org-confirm-babel-evaluate nil)
(org-default-notes-file (concat org-directory "/notes.org"))
(org-fontify-done-headline t)
(org-hide-emphasis-markers t)
(org-hide-leading-stars t)
(org-log-done t)
(org-pretty-entities t)
(org-src-preserve-indentation t)
(org-src-strip-leading-and-trailing-blank-lines t)
;; Ref https://orgmode.org/manual/Template-elements.html for more detail.
(org-agenda-files
(list "~/src/org"
"~/src/git.mitchty.net/mitchty/dotfiles"))
;; "#+TITLE: %a\n#+ROAM_KEY: %U\n\n [[%U][%U]]\n"
(org-capture-templates
'(
;; TODO: make this crap work somehow
;; ("w" "website"
;; entry (file (capture-date-file "~/src/org/ref/url" "org"))
;; ;; "#+TITLE: %a\n#+ROAM_KEY: %U\n\n%? [[%U][%U]]\n"
;; "%?"
;; :prepend t :empty-lines 1)
;; ("u" "unsorted note"
;; entry (file capture-date-file "~/src/org/unsorted" "org")
;; "\n* %?\nRandom Note entered on %U\n %i\n %a\n"
;; :prepend t :empty-lines 1)
;; ("r" "ref url"
;; entry (file capture-date-file "~/src/org/ref/url")
;; "\n* %?\nRandom Note entered on %U\n %i\n %a\n"
;; :prepend t :empty-lines 1)
("d" "deadline"
entry (file+headline org-default-notes-file "Todos")
"* PRIO %? \nDEADLINE: %t"
:prepend t :empty-lines 1 :clock-in t :clock-resume t)
("t" "todo"
entry (file+headline org-default-notes-file "Todos")
"* TODO %?\n %i\n %a\n"
:prepend t :empty-lines 1 :clock-in t :clock-resume t)
("n" "note"
entry (file+headline org-default-notes-file "Notes")
"\n* %?\nRandom Note entered on %U\n %i\n %a\n"
:prepend t :empty-lines 1 :clock-in t :clock-resume t)
("m" "email todo"
entry (file+headline org-default-notes-file "Inbox")
"\n* TODO %?, Link: %a\n"
:prepend t :empty-lines 1 :clock-in t :clock-resume t)
("u" "urls"
entry (file+headline org-default-notes-file "Urls")
"\n** TODO read url :url:\n[[%?]]\n"
:prepend t :empty-lines 1)
("i" "interruption"
entry (file+headline org-default-notes-file "Interruptions")
"\n* BLOCKED by %? :BLOCKED:\n%t"
:prepend t :empty-lines 1 :clock-in t :clock-resume t)
("j" "journal"
entry (file (concat org-directory "/journal.org"))
"* %?\n%U\n"
:prepend t :empty-lines 1 :clock-in t :clock-resume t)
)))
Ref:
Starting out simple..ish.
(use-package org-roam
:after org
:ensure t
:hook after-init
:custom
(org-roam-directory "~/src/org")
(org-roam-index-file "~/src/org/roam.org")
(org-roam-tag-sources '(prop all-directories))
(org-roam-capture-templates
'(("d" "default" plain (function org-roam--capture-get-point)
"%?"
:file-name "~/src/org/${slug}"
:unnarrowed t
:head "#+TITLE: ${title}\n")))
(org-roam-capture-ref-templates
'(("r" "ref" plain (function org-roam-capture--get-point)
"%?"
:file-name "~/src/org/ref/${slug}")
:unnarrowed t
:head "#+TITLE: ${title}\n#+ROAM_KEY: ${ref}\n- source :: ${ref}\n"))
:bind
(:map org-roam-mode-map
(("C-c n l" . org-roam)
("C-c n f" . org-roam-find-file)
("C-c n g" . org-roam-graph))
:map org-mode-map
(("C-c n i" . org-roam-insert))
(("C-c n I" . org-roam-insert-immediate))))
Validate that this installs from scratch fine, blocking babel executions is ass.
(use-package ob-async :after org :ensure t)
Figure out the customization needed here.
(use-package org-habit :after org :ensure t :custom (org-habit-graph-column 44) (org-habit-preceding-days 31) (org-habit-following-days 7))
https://github.com/integral-dw/org-superstar-mode
(use-package org-bullets
:after org
:ensure t
:custom
(org-bullets-bullet-list '("◉" "○" "✸" "✿" "✜" "◆" "▶"))
(org-ellipsis "↴")
:hook (org-mode . org-bullets-mode)
:config
(when window-system
(let* ((variable-tuple (cond ((x-list-fonts "Source Sans Pro") '(:font "Source Sans Pro"))
((x-list-fonts "Lucida Grande") '(:font "Lucida Grande"))
((x-list-fonts "Verdana") '(:font "Verdana"))
((x-family-fonts "Sans Serif") '(:family "Sans Serif"))
(nil (warn "Cannot find a Sans Serif Font."))))
(base-font-color (face-foreground 'default nil 'default))
(headline `(:inherit default :weight bold :foreground ,base-font-color)))
(custom-theme-set-faces 'user
`(org-level-8 ((t (,@headline ,@variable-tuple))))
`(org-level-7 ((t (,@headline ,@variable-tuple))))
`(org-level-6 ((t (,@headline ,@variable-tuple))))
`(org-level-5 ((t (,@headline ,@variable-tuple))))
`(org-level-4 ((t (,@headline ,@variable-tuple :height 1.1))))
`(org-level-3 ((t (,@headline ,@variable-tuple :height 1.25))))
`(org-level-2 ((t (,@headline ,@variable-tuple :height 1.5))))
`(org-level-1 ((t (,@headline ,@variable-tuple :height 1.75))))
`(org-document-title ((t (,@headline ,@variable-tuple :height 1.5 :underline nil)))))))
(font-lock-add-keywords 'org-mode
'(("^ +\\([-*]\\) "
(0 (prog1 () (compose-region (match-beginning 1) (match-end 1) "•"))))))
)
TODO: testing
(use-package org-num :load-path "lisp/" :after org :hook (org-mode . org-num-mode))
Its tangle is set to no…
(require 'ox-latex)
ox-latex
(unless (boundp 'org-latex-classes)
(setq org-latex-classes nil))
nil
(add-to-list 'org-latex-classes
'("article"
"\\documentclass{article}"
("\\section{%s}" . "\\section*{%s}")))
Flycheck for on the fly checking of code.
(use-package flycheck :ensure t :custom (flycheck-indication-mode 'left-fringe) :hook (prog-mode . flycheck-mode))
TODO: see if this is better for error messages
(use-package pos-tip :after flycheck :hook (flycheck-mode . flycheck-pos-tip-mode))
Need to vet this, used it more when I did more c. But its handy for non standard pkg-config setups.
Not tangled into the config intentionally.
(defun pkg-config-add-lib-cflags (pkg-config-lib)
"This function will add necessary header file path of a
specified by `pkg-config-lib' to `flycheck-clang-include-path', which make it
completionable by auto-complete-clang"
(interactive "spkg-config lib: ")
(if (executable-find "pkg-config")
(if (= (shell-command
(format "pkg-config %s" pkg-config-lib))
0)
(setq flycheck-clang-include-path
(append flycheck-clang-include-path
(split-string
(shell-command-to-string
(format "pkg-config --cflags-only-I %s"
pkg-config-lib)))))
(message "Error, pkg-config lib %s not found." pkg-config-lib))
(message "Error: pkg-config tool not found.")))
Auto complete functionality is nice to have.
(use-package auto-complete :ensure t :init (require 'auto-complete-config) (ac-config-default) (global-auto-complete-mode t) )
Helpfully inserts matching parens, can be a pita too.
(use-package smartparens :ensure t :hook (prog-mode . smartparens-mode))
Makes matching parens easier.
(use-package rainbow-delimiters :ensure t :hook (prog-mode . rainbow-delimiters-mode))
Make buffer names unique based on their directory and not have <N> or other nonsense.
(require 'uniquify) (custom-set-variables '(uniquify-buffer-name-style 'post-forward))
Desktop saving of session information handy to keep the same buffers between sessions.
(require 'desktop)
(desktop-save-mode 1)
(custom-set-variables
'(desktop-restore-eager 5)
'(desktop-path '("~/.emacs.d"))
'(desktop-dirname "~/.emacs.d")
'(desktop-base-file-name "desktop")
)
(defun local-desktop-save ()
(interactive)
(if (eq (desktop-owner) (emacs-pid))
(desktop-save desktop-dirname)))
REMOVE ME && TODO IF THIS WORKS
Saves buffers like with auto-save but on focus loss, when idle etc…
(use-package super-save :ensure t :config (super-save-mode +1) (setq super-save-auto-save-when-idle t) (setq auto-save-default nil) )
Highlight TODO/FIXME type messages in comments.
(use-package fic-mode :ensure t :hook (prog-mode . fic-mode))
(use-package git-gutter :ensure t :config (global-git-gutter-mode t) )
(use-package clang-format :ensure t :bind (([C-M-tab] . clang-format-region)) )
(use-package hideshow
:ensure t
:bind ("C-c s" . hs-toggle-hiding)
)
(use-package ggtags :ensure t)
Completion tips.
(use-package company :ensure t :hook (after-init . global-company-mode))
For.. yaml
(use-package yaml-mode :ensure t)
So I write gooder. Me fail English? Thats unpossible.
(use-package writegood-mode :ensure t)
(use-package rust-mode :commands rust-mode :defer t)
Compress down python configuration a bit.
(use-package python
:after company-mode
:commands python-mode
:mode ("\\.py\\'" . python-mode)
:config
(add-hook 'python-mode-hook'
(lambda ()
(push '("lambda" . ?λ) prettify-symbols-alist)
(push '("<=" . ?≤) prettify-symbols-alist)
(push '(">=" . ?≥) prettify-symbols-alist)
(push '("==" . ?≡) prettify-symbols-alist)
(push '("/=" . ?≢) prettify-symbols-alist)
(push '("&&" . ?∧) prettify-symbols-alist)
(push '("||" . ?∨) prettify-symbols-alist)
(push '("not" . ?¬) prettify-symbols-alist)
(push '("None" . ?⊥) prettify-symbols-alist)
(prettify-symbols-mode)
)
)
)
(use-package company-anaconda
:after python
:config
(add-to-list 'company-backends 'company-anaconda)
(add-hook 'python-mode-hook 'anaconda-mode)
)
(use-package pytest
:after python
:bind ("C-c t" . pytest-one)
)
(use-package pymacs :after python)
Need to make haskell source be all pretty.
(use-package haskell-mode
:defer t
:config
(add-hook 'haskell-mode-hook 'interactive-haskell-mode)
(add-hook 'haskell-mode-hook 'turn-on-haskell-indentation)
(add-hook 'haskell-mode-hook'
(lambda ()
(push '("()" . ?∅) prettify-symbols-alist)
(push '("\\" . ?λ) prettify-symbols-alist)
(push '("pi" . ?π) prettify-symbols-alist)
(push '("=>" . ?⇒) prettify-symbols-alist)
(push '("->" . ?→) prettify-symbols-alist)
(push '("<-" . ?←) prettify-symbols-alist)
(push '("<=" . ?≤) prettify-symbols-alist)
(push '(">=" . ?≥) prettify-symbols-alist)
(push '("==" . ?≡) prettify-symbols-alist)
(push '("/=" . ?≢) prettify-symbols-alist)
(push '("!!" . "‼") prettify-symbols-alist)
(push '("&&" . ?∧) prettify-symbols-alist)
(push '("||" . ?∨) prettify-symbols-alist)
(push '("~>" . ?⇝) prettify-symbols-alist)
(push '("-<" . ?↢) prettify-symbols-alist)
(push '("not" . ?¬) prettify-symbols-alist)
(push '("forall" . ?∀) prettify-symbols-alist)
(push '("sqrt" . ?√) prettify-symbols-alist)
(push '("undefined" . ?⊥) prettify-symbols-alist)
(prettify-symbols-mode)
)
)
(add-to-list 'completion-ignored-extensions ".hi")
:custom
(haskell-program-name "ghci")
(haskell-process-type 'cabal-repl)
(haskell-tags-on-save t)
)
(use-package dante
:after haskell-mode
:config
(add-hook 'haskell-mode-hook 'dante-mode)
)
(use-package hindent
:if (executable-find "hindent")
:after haskell-mode
:config
(add-hook 'haskell-mode-hook 'hindent-mode)
)
(use-package flycheck-haskell :after haskell-mode)
(use-package flycheck-hdevtools
:after haskell-mode
:config
(add-hook 'haskell-mode-hook 'flycheck-mode)
)
(use-package ghc
:if (executable-find "ghc-mod")
:after haskell-mode
:config
(autoload 'ghc-init "ghc" nil t)
(autoload 'ghc-debug "ghc" nil t)
(add-hook 'haskell-mode-hook (lambda () (ghc-init)))
)
(use-package idris-mode
:defer t
:config
(add-to-list 'completion-ignored-extensions ".ibc")
(add-hook 'idris-mode-hook'
(lambda ()
(push '("()" . ?∅) prettify-symbols-alist)
(push '("\\" . ?λ) prettify-symbols-alist)
(push '("pi" . ?π) prettify-symbols-alist)
(push '("=>" . ?⇒) prettify-symbols-alist)
(push '("->" . ?→) prettify-symbols-alist)
(push '("<-" . ?←) prettify-symbols-alist)
(push '("<=" . ?≤) prettify-symbols-alist)
(push '(">=" . ?≥) prettify-symbols-alist)
(push '("==" . ?≡) prettify-symbols-alist)
(push '("/=" . ?≢) prettify-symbols-alist)
(push '("!!" . "‼") prettify-symbols-alist)
(push '("&&" . ?∧) prettify-symbols-alist)
(push '("||" . ?∨) prettify-symbols-alist)
(push '("~>" . ?⇝) prettify-symbols-alist)
(push '("-<" . ?↢) prettify-symbols-alist)
(push '("not" . ?¬) prettify-symbols-alist)
(push '("forall" . ?∀) prettify-symbols-alist)
(push '("sqrt" . ?√) prettify-symbols-alist)
(push '("undefined" . ?⊥) prettify-symbols-alist)
(prettify-symbols-mode)
)
)
)
Make undo more useful, and treelike.
(use-package undo-tree
:ensure t
:config
(global-undo-tree-mode)
(defadvice undo-tree-visualize (around undo-tree-split-side-by-side activate)
"Split undo-tree side-by-side"
(let ((split-height-threshold nil)
(split-width-threshold 0))
ad-do-it)
)
:bind
("C-x u" . undo-tree-visualize)
)
Color variables for easy identification, its like a rainbow puked over everything opened in prog-mode-hook.
(use-package color-identifiers-mode :defer t :hook (prog-mode . color-identifiers-mode))
Highlight a variable when you're selecting it, helps in reviewing code to see where it exists.
(use-package idle-highlight-mode :hook (prog-mode . idle-highlight-mode))
Instead of text might as well get a decent mode hook going here.
(use-package nixos-options :defer t) (use-package company-nixos-options :after company :defer t)
(use-package nix-mode
:config
(setq flycheck-command-wrapper-function
(lambda (command) (apply 'nix-shell-command (nix-current-sandbox) command))
flycheck-executable-find
(lambda (cmd) (nix-executable-find (nix-current-sandbox) cmd)))
(add-to-list 'company-backends 'company-nixos-options)
)
(use-package dockerfile-mode :defer t)
Switch to rtags, or maybe even nuke entirely?
(use-package xcscope :defer t :config (cscope-setup))
(use-package rg :ensure t :defer t)
Common mode defaults I think are sensible.
(add-to-list 'auto-mode-alist '("\\.[chm]\\'" . c-mode))
(add-hook 'c-mode-common-hook
'(lambda ()
(global-set-key "\C-x\C-m" 'compile)
(setq flycheck-clang-language-standard "c11")
(setq flycheck-idle-change-delay 2)
(setq flycheck-highlighting-mode 'symbols)
;; later...
;; (add-hook 'before-save-hook 'clang-format-buffer nil t)
(c-toggle-auto-state 1)
(setq-default c-basic-offset 2
tab-width 2
indent-tabs-mode nil
c-electric-flag t
indent-level 2
c-default-style "bsd"
backward-delete-function nil)
))
Why is this broken? Figure out why its tangle is no.
(add-hook 'emacs-lisp-hook
(lambda ()
(define-key emacs-lisp-map
"\C-x\C-e" 'pp-eval-last-sexp)
(define-key emacs-lisp-map
"\r" 'reindent-then-newline-and-indent)))
(add-hook 'python-mode-hook
'(lambda ()
(flycheck-select-checker 'python-flake8)
)
)
(autoload 'sh--mode "sh-mode" "mode for shell stuff" t)
(add-to-list 'auto-mode-alist '("\\.sh$\\'" . sh-mode))
(add-to-list 'auto-mode-alist '("\\.[zk]sh$\\'" . sh-mode))
(add-to-list 'auto-mode-alist '("\\.bash$\\'" . sh-mode))
(add-to-list 'auto-mode-alist '("\\[.].*shrc$\\'" . sh-mode))
(add-to-list 'auto-mode-alist '("sourceme$\\'" . sh-mode))
(add-hook 'sh-mode-hook
'(lambda ()
(setq sh-basic-offset 2 sh-indentation 4
sh-indent-for-case-label 0 sh-indent-for-case-alt '+)))
(fset 'perl-mode 'cperl-mode)
(add-hook 'cperl-mode-hook
'(lambda ()
(setq indent-tabs-mode t)
(setq tab-width 8)
(setq cperl-indent-level 4)
(setq tab-stop-list (number-sequence 4 200 4))
(setq cperl-tab-always-indent t)
(setq cperl-indent-parens-as-block t)
)
)
Review if this is worth keeping around, methinks there should be something better like yasnippet out there, this is all old af hacks
Use auto-insert-mode to insert in templates for blank files.
So first up, add auto-insert to find-file-hooks so we insert straight away. Also setup the copyright bit to minimally put in name.
(add-hook 'find-file-hooks 'auto-insert) (defvar auto-insert-copyright (user-full-name))
Create auto-insert-alist so all the mode lists are the same
(defvar auto-insert-alist '(()))
(setq auto-insert-alist
(append
'(
((c-mode . "c")
nil
"/*\n"
"File: " (file-name-nondirectory buffer-file-name) "\n"
"Copyright: " (substring (current-time-string) -4) " " auto-insert-copyright "\n"
"Description: " _ "\n"
"*/\n"
"#include <stdio.h>\n"
"#include <stdlib.h>\n\n"
"int main(int argc, char **argv) {\n"
" return 0;\n"
"}\n"
)
)
auto-insert-alist)
)
(setq auto-insert-alist
(append
'(
((emacs-lisp-mode . "elisp")
nil
";;-*-mode: emacs-lisp; coding: utf-8;-*-\n"
";; File: " (file-name-nondirectory buffer-file-name) "\n"
";; Copyright: " (substring (current-time-string) -4) " " auto-insert-copyright "\n"
";; Description: " _ "\n"
)
)
auto-insert-alist)
)
(setq auto-insert-alist
(append
'(((python-mode . "python")
nil
"#!/usr/bin/env python\n"
"# -*-mode: Python; coding: utf-8;-*-\n"
"# File: " (file-name-nondirectory buffer-file-name) "\n"
"# Copyright: " (substring (current-time-string) -4) " " auto-insert-copyright "\n"
"# Description: " _ "\n\n"
)
)
auto-insert-alist)
)
(setq auto-insert-alist
(append
'(
((sh-mode . "sh")
nil
"#!/usr/bin/env sh\n"
"#-*-mode: Shell-script; coding: utf-8;-*-\n"
"# File: " (file-name-nondirectory buffer-file-name) "\n"
"# Copyright: " (substring (current-time-string) -4) " " auto-insert-copyright "\n"
"# Description: " _ "\n"
"_base=$(basename \"$0\")\n"
"_dir=$(cd -P -- \"$(dirname -- \"$(command -v -- \"$0\")\")\" && pwd -P || exit 126)\n"
"export _base _dir\n"
)
)
auto-insert-alist)
)
Load this up last to allow for local customization if needed and to keep from custom writing to the init.el file.
(setq custom-file "~/.emacs.d/custom.el") (load custom-file 'noerror)
Probably need to check if this file exists first…
(load-file "~/.emacs.d/local.el")
Stuff thats getting tested…
Iffy…. Does some jank ass wack stuff in fullscreen mode on cocoa emacs in macos.
(use-package mini-frame :ensure t :config (mini-frame-mode t) :custom (mini-frame-show-parameters '((top . 10)))) ;; (width . 0.7) ;; (left . 0.5))))