1431 lines
47 KiB
Org Mode
1431 lines
47 KiB
Org Mode
#+PROPERTY: header-args:emacs-lisp :tangle yes
|
|
#+TITLE: Emacs Configuration
|
|
* Literate emacs configuration
|
|
|
|
I can never rembember what various configs do. Jumping on this literate emacs
|
|
config to see if it helps!
|
|
|
|
** Set some ENV vars
|
|
|
|
These are needed to make emacs aware of various things (like Go binaries,
|
|
etc). I have them here because sometimes when emacs is launched from ~rofi~
|
|
or similar it doesn't have the same ENV as it does when launching from the
|
|
shell.
|
|
|
|
#+begin_src emacs-lisp
|
|
(defun expand-if-exists (d)
|
|
;; expand-if-exists(d) expands d only if d exists
|
|
(if (file-exists-p d)
|
|
(expand-file-name d)))
|
|
|
|
(let ((paths
|
|
'(
|
|
"/usr/local/bin"
|
|
"/usr/local/go/bin"
|
|
"/usr/local/MacGPG2/bin"
|
|
"/Library/TeX/texbin"
|
|
"/usr/local/jdk-11/bin"
|
|
"/usr/ports/infrastructure/bin"
|
|
"~/bin"
|
|
"~/.nix-profile/bin"
|
|
"~/go/bin"
|
|
"~/opt/bin"
|
|
"/usr/local/plan9/bin"
|
|
)))
|
|
|
|
(setenv "PATH" (concat (getenv "PATH") (mapconcat 'expand-if-exists (remove nil paths) ":")))
|
|
(setq exec-path (append exec-path (remove "" (split-string (getenv "PATH") ":")))))
|
|
#+end_src
|
|
|
|
** Start the emacs server
|
|
|
|
Starting as a server lets me connect externally to do things like change
|
|
themes, save buffers via cron and other such dumbary!
|
|
|
|
#+begin_src emacs-lisp
|
|
(load "server")
|
|
(unless (server-running-p) (server-start))
|
|
#+end_src
|
|
|
|
** OpenBSD Lockups
|
|
|
|
For some reason OpenBSD hangs, these seem to help a bit
|
|
#+begin_src emacs-lisp
|
|
(setq x-select-enable-clipboard-manager nil)
|
|
(setq x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING))
|
|
(setf x-selection-timeout 500)
|
|
#+end_src
|
|
|
|
** Interface and Behavior
|
|
*** Interface
|
|
|
|
Global font
|
|
#+begin_src emacs-lisp
|
|
;; This is currently set in ~/.Xresources - for some reason emacs doesn't like the line below
|
|
(set-frame-font "Go Mono")
|
|
#+end_src
|
|
|
|
Use 80 columns, this helps keep things readable when windows are split
|
|
#+begin_src emacs-lisp
|
|
(setq whitespace-style '(trailing lines space-before-tab)
|
|
whitespace-line-column 80)
|
|
(setq-default fill-column 80)
|
|
#+end_src
|
|
|
|
I know I am in emacs, don't need to see the startup screen.
|
|
#+begin_src emacs-lisp
|
|
(setq inhibit-startup-screen t)
|
|
#+end_src
|
|
|
|
If we are on OpenBSD, fill the scratch buffer with fortune \o/.
|
|
|
|
#+begin_src emacs-lisp
|
|
(if (file-executable-p "/usr/games/fortune")
|
|
(setq initial-scratch-message
|
|
(concat
|
|
(shell-command-to-string "fortune | sed -e 's/^/;; /g'")
|
|
"\n\n")))
|
|
#+end_src
|
|
|
|
**** Use UTF8 where ever possible
|
|
#+begin_src emacs-lisp
|
|
(prefer-coding-system 'utf-8)
|
|
(set-default-coding-systems 'utf-8)
|
|
(set-terminal-coding-system 'utf-8)
|
|
(set-keyboard-coding-system 'utf-8)
|
|
#+end_src
|
|
|
|
**** Change various UI bits
|
|
#+begin_src emacs-lisp
|
|
(tool-bar-mode -1)
|
|
(menu-bar-mode -1)
|
|
(scroll-bar-mode -1)
|
|
(column-number-mode +1)
|
|
(global-font-lock-mode 1)
|
|
#+end_src
|
|
|
|
**** No GNU ls here
|
|
#+begin_src emacs-lisp
|
|
(setq ls-lisp-use-insert-directory-program nil)
|
|
(require 'ls-lisp)
|
|
#+end_src
|
|
|
|
*** Behavior
|
|
|
|
Switch various defaults to be more comfortable for myself.
|
|
|
|
#+begin_src emacs-lisp
|
|
(fset 'yes-or-no-p 'y-or-n-p)
|
|
(show-paren-mode t)
|
|
|
|
(setq desktop-dirname "~/.emacs.d/"
|
|
desktop-base-file-name "emacs.desktop"
|
|
desktop-base-lock-name "lock"
|
|
desktop-path (list desktop-dirname)
|
|
desktop-save t
|
|
desktop-files-not-to-save "^$" ;reload tramp paths
|
|
desktop-load-locked-desktop nil
|
|
desktop-auto-save-timeout 30)
|
|
(desktop-save-mode 1)
|
|
|
|
(setq backup-directory-alist '(("." . "~/.emacs-saves")))
|
|
(setq auto-mode-alist
|
|
(append
|
|
(list
|
|
'("\\.gpg$" . sensitive-minor-mode)
|
|
)
|
|
auto-mode-alist))
|
|
(setq auth-sources
|
|
'((:source "~/.netrc")))
|
|
#+end_src
|
|
|
|
Use spelling and auto-fill when we are in text mode.
|
|
|
|
#+begin_src emacs-lisp
|
|
(add-hook 'text-mode-hook (lambda ()
|
|
(auto-fill-mode 1)
|
|
(turn-on-flyspell)))
|
|
#+end_src
|
|
|
|
This fixes some tramp "waiting for prompt" errors.
|
|
#+begin_src emacs-lisp
|
|
;;(setq trarmp-shell-prompt-pattern "\\(?:^\\|\r\\)[^]#$%>λ\n]*#?[]#$%>λ].* *\\(^[\\[[0-9;]*[a-zA-Z] *\\)*")
|
|
;;(require 'tramp-sh nil t)
|
|
;;(setf tramp-ssh-controlmaster-options
|
|
;; (concat
|
|
;; "-o ControlPath=/tmp/ssh-%%r@%%h:%%p "
|
|
;; "-o ControlMaster=auto -o ControlPersist=yes"))
|
|
#+end_src
|
|
|
|
If things _aren't_ working the way we want:
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq tramp-verbose 6)
|
|
#+end_src
|
|
|
|
** Include ports site-lisp
|
|
|
|
On OpenBSD various packages (mu, git.. etc) install elisp things into a global
|
|
directory, this makes sure we include it.
|
|
|
|
#+begin_src emacs-lisp
|
|
(if (file-directory-p "/usr/local/share/emacs/site-lisp")
|
|
(add-to-list 'load-path "/usr/local/share/emacs/site-lisp/"))
|
|
#+end_src
|
|
|
|
** Unset custom-file
|
|
|
|
The customization file mostly just causes churn in the SCM so we disable it
|
|
here.
|
|
#+begin_src emacs-lisp
|
|
(setq custom-file (make-temp-file ""))
|
|
#+end_src
|
|
|
|
** Ensure packages are pinned and installed
|
|
|
|
This makes sure ~use-package~ installs things (and makes it so we don't need
|
|
~:ensure t~ set for every package.
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq use-package-always-ensure t)
|
|
;;(setq use-package-always-pin "melpa-stable")
|
|
#+end_src
|
|
|
|
* Packages
|
|
** parchment-theme
|
|
This is a nice theme that resembles acme in plan9. Minimal.
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package parchment-theme
|
|
:config (load-theme 'parchment t))
|
|
#+end_src
|
|
|
|
** keychain-environment
|
|
|
|
I make heavy use of ~ssh-agent~ this lets emacs pickup / use the existing
|
|
agents I have running.
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package keychain-environment
|
|
;;:pin "melpa"
|
|
:init
|
|
(keychain-refresh-environment))
|
|
#+end_src
|
|
|
|
** ivy
|
|
|
|
~ivy~ is fantastic. It gives me nice visual search for buffers,
|
|
code.. etc. Combined with ~smex~ for sorting (shows last used things first) and
|
|
~counsel~ (extends ivy into various areas like the help stuff).
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package counsel)
|
|
(setq smex-save-file (expand-file-name "~/.emacs.d/smex.save"))
|
|
(use-package smex)
|
|
(use-package ivy
|
|
:hook (after-init . ivy-mode)
|
|
:bind
|
|
("C-s" . swiper)
|
|
("M-x" . counsel-M-x)
|
|
("C-x C-f" . counsel-find-file)
|
|
("C-x b" . ivy-switch-buffer))
|
|
#+end_src
|
|
|
|
** magit
|
|
|
|
Magit is a awesome. Not sure what else to say about it. :P
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package magit
|
|
:bind ("C-c m" . magit-status)
|
|
:init
|
|
(setq magit-completing-read-function 'ivy-completing-read))
|
|
#+end_src
|
|
|
|
** flycheck
|
|
|
|
~flycheck~ does automatic syntax checking for most things
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package flycheck
|
|
:init (global-flycheck-mode))
|
|
#+end_src
|
|
|
|
- [2020-05-29 Fri] Unfortunately it clobbers the "C-c !" prefix, so we need
|
|
to add this to get it back:
|
|
|
|
#+begin_src emacs-lisp
|
|
(define-key flycheck-mode-map (kbd "C-c !") 'org-time-stamp-inactive)
|
|
#+end_src
|
|
|
|
** lsp-mode
|
|
|
|
~lsp-mode~ supports language servers for various things. I pretty much only
|
|
care about Go and Ruby.
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package lsp-mode
|
|
:hook ((go-mode . lsp-deferred)
|
|
(ruby-mode . lsp))
|
|
:commands (lsp lsp-deferred))
|
|
#+end_src
|
|
|
|
** company and friends
|
|
|
|
~company~ allows for auto-completion of various things. It can interface with ~lsp-mode~ to complete
|
|
things like Go.
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package company
|
|
:config
|
|
(setq company-tooltip-limit 20
|
|
company-minimum-prefix-length 1
|
|
company-idle-delay .3
|
|
company-echo-delay 0)
|
|
:hook (prog-mode . company-mode))
|
|
#+end_src
|
|
|
|
** gitgutter
|
|
This gives me a nice in-ui way to see modifications and what not.
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package git-gutter
|
|
:hook
|
|
(after-init . global-git-gutter-mode))
|
|
#+end_src
|
|
|
|
** nix
|
|
|
|
Add support for nix files. I don't use nix much atm, but it was recently
|
|
ported to OpenBSD, so I am hopeful I can start using it there more!
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package nix-mode
|
|
:mode "\\.nix\\'")
|
|
#+end_src
|
|
|
|
** shell
|
|
|
|
I don't often use the shell from emacs, but when I do these bits make it
|
|
easier for me to treat it like a regular shell.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; Kill terminal buffers on exit so I din't have to kill the buffer after I exit.
|
|
(defadvice term-handle-exit
|
|
(after term-kill-buffer-on-exit activate)
|
|
(kill-buffer))
|
|
#+end_src
|
|
|
|
** pinboard
|
|
|
|
A pinboard.in client
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package pinboard)
|
|
#+end_src
|
|
|
|
** restclient
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package restclient
|
|
;;:pin "melpa"
|
|
:mode (("\\.http$" . restclient-mode)))
|
|
#+end_src
|
|
|
|
** sr-speedbar
|
|
|
|
Speedbar is almost perfect.. If it only ran in the current frame!! :D
|
|
|
|
**** Enter sr-speedbar
|
|
#+begin_src emacs-lisp
|
|
;;; sr-speedbar.el --- Same frame speedbar
|
|
|
|
;; Author: Sebastian Rose <sebastian_rose@gmx.de>
|
|
;; Maintainer: Sebastian Rose <sebastian_rose@gmx.de>
|
|
;; Peter Lunicks <plunix@users.sourceforge.net>
|
|
;; Copyright (C) 2008, 2009, Sebastian Rose, all rights reserved.
|
|
;; Copyright (C) 2008, 2009, Andy Stewart, all rights reserved.
|
|
;; Copyright (C) 2009, Peter Lunicks, all rights reversed.
|
|
;; Created: 2008
|
|
;; Version: 20200616
|
|
;; X-Original-Version: 0.1.10
|
|
;; Last-Updated: 2020-06-16
|
|
;; URL: http://www.emacswiki.org/emacs/download/sr-speedbar.el
|
|
;; Keywords: speedbar, sr-speedbar.el
|
|
;; Compatibility: GNU Emacs 22 ~ GNU Emacs 25
|
|
;;
|
|
;; Features required by this library:
|
|
;;
|
|
;; `speedbar' `advice' `cl'
|
|
;;
|
|
|
|
;;; This file is NOT part of GNU Emacs
|
|
|
|
;;; License
|
|
;;
|
|
;; 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, 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; see the file COPYING. If not, write to
|
|
;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
|
|
;; Floor, Boston, MA 02110-1301, USA.
|
|
|
|
;;; Commentary:
|
|
;;
|
|
;; The sr-speedbar.el was created just because I could not believe what I
|
|
;; read on http://www.emacswiki.org/cgi-bin/wiki/Speedbar. They wrote there
|
|
;; that it is not possible to show the speedbar in the same frame. But, as
|
|
;; we all know, ecb had this already. So I started as some kind of joke :)
|
|
;; But when I found it useful and use it all the time.
|
|
;;
|
|
;; Now you type windows key with 's' (`s-s' in Emacs) will show the speedbar
|
|
;; in an extra window, same frame. You can customize the initial width of the
|
|
;; speedbar window.
|
|
;;
|
|
;; Below are commands you can use:
|
|
;;
|
|
;; `sr-speedbar-open' Open `sr-speedbar' window.
|
|
;; `sr-speedbar-close' Close `sr-speedbar' window.
|
|
;; `sr-speedbar-toggle' Toggle `sr-speedbar' window.
|
|
;; `sr-speedbar-select-window' Select `sr-speedbar' window.
|
|
;; `sr-speedbar-refresh-turn-on' Turn on refresh speedbar content.
|
|
;; `sr-speedbar-refresh-turn-off' Turn off refresh speedbar content.
|
|
;; `sr-speedbar-refresh-toggle' Toggle refresh speedbar content.
|
|
;;
|
|
;; Enjoy! ;)
|
|
;;
|
|
|
|
;;; Installation:
|
|
;;
|
|
;; Copy sr-speedbar.el to your load-path and add to your ~/.emacs
|
|
;;
|
|
;; (require 'sr-speedbar)
|
|
;; (global-set-key (kbd "s-s") 'sr-speedbar-toggle)
|
|
;;
|
|
;; ... or any key binding you like.
|
|
;;
|
|
|
|
;;; Customize:
|
|
;;
|
|
;; M-x customize-group RET sr-speedbar RET
|
|
|
|
;;; Change log:
|
|
;; * 07 Jan 2021:
|
|
;; * Jacob First <jacob.first@member.fsf.org>
|
|
;; * Fix inconsistent window selection when opening speedbar on the right side vs. on the left.
|
|
;;
|
|
;; * 16 Jun 2020:
|
|
;; * Bo Yao <icerove@gmail.com> (submitted by him on 16 Jul 2018 to the Emacs Orphanage mirror version at GitHub)
|
|
;; * Always open file in most recently selected window (the one before switching to
|
|
;; sr-speedbar).
|
|
;;
|
|
;; * 25 Oct 2016:
|
|
;; * Hong Xu <hong@topbug.net>
|
|
;; * Fix compilation warning when `helm-alive-p' is not defined.
|
|
;;
|
|
;; * 04 Aug 2015:
|
|
;; * Tamas Levai <levait@tmit.bme.hu>:
|
|
;; * fix compilation warnings
|
|
;;
|
|
;; * 15 Sep 2014:
|
|
;; * Tu, Do Hoang <tuhdo1710@gmail.com>
|
|
;; * define `sr-speedbar-handle-other-window-advice' and `ad-advised-definition-p'
|
|
;; before defining `sr-speedbar-skip-other-window-p'. Othewise, `sr-speedbar'
|
|
;; fails to load at this stage.
|
|
;;
|
|
;; * Do not used advised `pop-to-buffer' when helm window is
|
|
;; alive. Otherwise another horizontal buffer is created inside
|
|
;; Helm buffer.
|
|
;;
|
|
;; * Uwe Koloska <kolewu@koloro.de>
|
|
;; * define `ad-advised-definition-p' only if it's not defined
|
|
;; fixes an error on Emacs 24.3 where `macrop' ist still named
|
|
;; `ad-macro-p'
|
|
;;
|
|
;; * 03 Aug 2014:
|
|
;; * Reuben Thomas <rrt@sc3d.org>:
|
|
;; * Reduce to a single width preference, and make it work properly on
|
|
;; startup.
|
|
;; * Miscellaneous tidying of documentation and comments.
|
|
;; * Remove version constant; should be using the package header, and it
|
|
;; was already way out of date.
|
|
;;
|
|
;; * 08 Jun 2014:
|
|
;; * Gregor Zattler:
|
|
;; * test if symbol `ad-advised-definition-p' is defined,
|
|
;; since Christian Brassats version test failed on emacs
|
|
;; 23.3.91.1
|
|
;;
|
|
;; * 05 May 2014:
|
|
;; * Christian Brassat:
|
|
;; * `ad-advised-definition-p' is not supported since Emacs 24.4.
|
|
;;
|
|
;; * 09 Mar 2013:
|
|
;; * Tharre:
|
|
;; * Remove Emacs 21 compatibility code as it fails to compile on Emacs 24.
|
|
;;
|
|
;; * 20 July 2009:
|
|
;; * Peter Lunicks:
|
|
;; * Add new option `sr-speedbar-right-side' to control which
|
|
;; side of the frame the speedbar appears on.
|
|
;;
|
|
;; * 18 Feb 2009:
|
|
;; * Andy Stewart:
|
|
;; * Fix bug between ECB and `sr-speedbar-close'.
|
|
;;
|
|
;; * 29 Jan 2009:
|
|
;; * Andy Stewart:
|
|
;; * Fix doc.
|
|
;;
|
|
;; * 13 Jan 2009:
|
|
;; * Andy Stewart:
|
|
;; * Use `emacs-major-version' instead comment for Emacs 21 compatibility.
|
|
;; * Rewrite advice for `pop-to-buffer' to avoid `pop-to-buffer' not effect
|
|
;; when have many dedicated window in current frame.
|
|
;; * Rewrite advice for `delete-other-windows' to avoid use common variable
|
|
;; `delete-protected-window-list' and use `window-dedicated-p' instead.
|
|
;; Remove variable `delete-protected-window-list' and function
|
|
;; `sr-speedbar-dedicated-match-protected-window-p'.
|
|
;;
|
|
;; * 04 Jan 2009:
|
|
;; * Andy Stewart:
|
|
;; * Add new option `sr-speedbar-auto-refresh' control refresh content.
|
|
;; * Add new functions:
|
|
;; `sr-speedbar-refresh-turn-on',
|
|
;; `sr-speedbar-refresh-turn-off',
|
|
;; `sr-speedbar-refresh-toggle'.
|
|
;; * Fix doc.
|
|
;;
|
|
;; * 30 Dec 2008:
|
|
;; * Andy Stewart:
|
|
;; * Rewrite advice for `delete-other-windows' for fix the bug
|
|
;; with window configuration save and revert.
|
|
;; * Rewrite advice for `delete-window', now just remember window
|
|
;; width before deleted, and can use `delete-window' do same effect
|
|
;; as command `sr-speedbar-close'.
|
|
;; * Add new option `sr-speedbar-max-width'.
|
|
;; Remember window width before hide, except larger than value of
|
|
;; `sr-speedbar-max-width'.
|
|
;; * Add new variable `delete-protected-window-list', for protected
|
|
;; special window don't deleted.
|
|
;; This variable is common for any extension that use dedicated
|
|
;; window.
|
|
;; * Fix doc.
|
|
;;
|
|
;; * 29 Dec 2008:
|
|
;; * Andy Stewart:
|
|
;; * Pick-up and refactory code that use `buffer-live-p' or `window-live-p',
|
|
;; and replace with `sr-speedbar-buffer-exist-p' and
|
|
;; `sr-speedbar-window-exist-p'.
|
|
;; * Rename some function with prefix `sr-speedbar-' to avoid
|
|
;; conflict with other functions.
|
|
;; * Pick-up the code that handle advice for `other-window',
|
|
;; and replace with function `sr-speedbar-handle-other-window-advice'.
|
|
;; * Clean up code, make more clear.
|
|
;;
|
|
;; * 21 Dec 2008:
|
|
;; * Andy Stewart:
|
|
;; * Fix the bug `sr-speedbar-open' and `sr-speedbar-close'.
|
|
;; * Fix doc.
|
|
;;
|
|
;; * 20 Dec 2008
|
|
;; * Andy Stewart:
|
|
;; * Fix `ad-advised-definition-p' error.
|
|
;; * Fix doc.
|
|
;;
|
|
;; * 17 Dec 2008
|
|
;; * Andy Stewart:
|
|
;; * Add new option `sr-speedbar-skip-other-window-p' and new advice
|
|
;; for `other-window', make user skip select `sr-speedbar' window
|
|
;; when use command `other-window'.
|
|
;; * Fix the name of advice, make more clear.
|
|
;; * Fix the bug `sr-speedbar-select-window' when no live window exist.
|
|
;; * Fix doc.
|
|
;;
|
|
;; * 16 Dec 2008:
|
|
;; * Andy Stewart:
|
|
;; * Fix the bug of `sr-speedbar-refresh', use `default-directory'
|
|
;; get refresh directory instead through function in `dired'.
|
|
;; * Fix `window-live-p' bug, check window valid value before use
|
|
;; `window-live-p' test `sr-speedbar-window'.
|
|
;; * Fix `buffer-live-p' bug, check buffer valid value before use
|
|
;; `buffer-live-p' test `speedbar-buffer'.
|
|
;; * Add advice `pop-to-buffer' to make function `display-buffer'
|
|
;; can pop-up window when just have two windows (one is `sr-speedbar'
|
|
;; window) in current frame.
|
|
;; * Add group `sr-speedbar'.
|
|
;; More better customize interface through `customize-group'.
|
|
;;
|
|
;; * 28 Sep 2008:
|
|
;; * Andy Stewart:
|
|
;; * Fix a bug, when `sr-speedbar-toggle' many times, window width
|
|
;; will increment automatically.
|
|
;; * Use around advices replace, make code simple.
|
|
;; * Use `sr-speedbar-open' replace `sr-speedbar-no-separate-frame'.
|
|
;; * Clean up code.
|
|
;;
|
|
;; * 28 Sep 2008:
|
|
;; * Sebastian:
|
|
;; * set `sr-speedbar-delete-windows' to nil to avoid
|
|
;; the removal of other windows.
|
|
;;
|
|
;; * 26 Jun 2008:
|
|
;; * Sebastian:
|
|
;; * Added Andy Stewart's patch to refresh the speedbar's contents.
|
|
;; Thanks for this one!
|
|
;;
|
|
;; * Init:
|
|
;; * Sebastian:
|
|
;; * Added some lines to get it working:
|
|
;; * splitting the window and remember it,
|
|
;; * changing the way speedbar finds a file.
|
|
;; * File view of speedbar is now working all right.
|
|
;; * C-x 1 in other window deletes speedbar-window, just calling
|
|
;; M-x sr-speedbar-no-separate-frame again is fine now.
|
|
;; * Toggle speedbar works, width is save when toggling.
|
|
;; * Recalculate speedbar width if window-width - speedbar-width <= 0
|
|
;; * Speedbar window is now dedicated to speedbar-buffer.
|
|
;;
|
|
|
|
;;; Acknowledgements:
|
|
;;
|
|
;; All emacsers ... :)
|
|
;;
|
|
|
|
;;; Bug
|
|
;;
|
|
;;
|
|
|
|
;;; TODO
|
|
;;
|
|
;;
|
|
;;
|
|
|
|
;;; Require
|
|
(require 'speedbar)
|
|
(require 'advice)
|
|
(require 'cl-lib)
|
|
(eval-when-compile
|
|
(require 'cl))
|
|
|
|
;;; Code:
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; User Customization ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
(defgroup sr-speedbar nil
|
|
"Same frame speedbar."
|
|
:group 'speedbar)
|
|
|
|
(defcustom sr-speedbar-default-width 40
|
|
"Initial width of `sr-speedbar-window' under window system."
|
|
:type 'integer
|
|
:group 'sr-speedbar)
|
|
|
|
(defcustom sr-speedbar-max-width 50
|
|
"The max width limit that window allowed.
|
|
Default, if hide `sr-speedbar' window will remember
|
|
window width, except the window width larger than
|
|
this value."
|
|
:type 'integer
|
|
:group 'sr-speedbar)
|
|
|
|
(defcustom sr-speedbar-auto-refresh t
|
|
"Automatically refresh speedbar content when changed directory.
|
|
Default is t."
|
|
:type 'boolean
|
|
:set (lambda (symbol value)
|
|
(set symbol value))
|
|
:group 'sr-speedbar)
|
|
|
|
(defcustom sr-speedbar-right-side t
|
|
"Show the speedbar to the right side of the current window.
|
|
If nil, the speedbar will appear on the left.
|
|
Default is t."
|
|
:type 'boolean
|
|
:set (lambda (symbol value)
|
|
(set symbol value))
|
|
:group 'sr-speedbar)
|
|
|
|
(defcustom sr-speedbar-delete-windows nil
|
|
"Allow the speedbar to delete other windows before showing up.
|
|
If nil, speedbar will not touch your window configuration.
|
|
Otherwise `delete-other-windows' will be called before showing
|
|
the speedbar.
|
|
|
|
Default is nil."
|
|
:type 'boolean
|
|
:group 'sr-speedbar)
|
|
|
|
(if (not (fboundp 'ad-advised-definition-p))
|
|
(defun ad-advised-definition-p (definition)
|
|
"Return non-nil if DEFINITION was generated from advice information."
|
|
(if (or (ad-lambda-p definition)
|
|
(macrop definition)
|
|
(ad-compiled-p definition))
|
|
(let ((docstring (ad-docstring definition)))
|
|
(and (stringp docstring)
|
|
(get-text-property 0 'dynamic-docstring-function docstring))))))
|
|
|
|
(defun sr-speedbar-handle-other-window-advice (activate)
|
|
"Handle advice for function `other-window'.
|
|
If ACTIVATE is `non-nil' enable advice `sr-speedbar-other-window-advice'.
|
|
Otherwise disable it."
|
|
(if activate
|
|
(ad-enable-advice 'other-window 'after 'sr-speedbar-other-window-advice)
|
|
(ad-disable-advice 'other-window 'after 'sr-speedbar-other-window-advice))
|
|
(ad-activate 'other-window))
|
|
|
|
(defcustom sr-speedbar-skip-other-window-p nil
|
|
"Whether skip `sr-speedbar' window with `other-window'.
|
|
Default, can use `other-window' select window in cyclic
|
|
ordering of windows. But sometimes we don't want select
|
|
`sr-speedbar' window use `other-window'.
|
|
Just want make `sr-speedbar' window as a view sidebar.
|
|
|
|
So please turn on this option if you want skip
|
|
`sr-speedbar' window with `other-window'.
|
|
|
|
Default is nil."
|
|
:type 'boolean
|
|
:set (lambda (symbol value)
|
|
(set symbol value)
|
|
(if (fboundp 'ad-advised-definition-p)
|
|
(when (ad-advised-definition-p 'other-window)
|
|
(sr-speedbar-handle-other-window-advice value))
|
|
(when (ad-is-advised 'other-window)
|
|
(sr-speedbar-handle-other-window-advice value))))
|
|
:group 'sr-speedbar)
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Constant ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
(defconst sr-speedbar-buffer-name "*SPEEDBAR*"
|
|
"The buffer name of sr-speedbar.")
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Variables ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
(defvar sr-speedbar-width sr-speedbar-default-width
|
|
"Initial width of speedbar-window.")
|
|
|
|
(defvar sr-speedbar-window nil
|
|
"Speedbar window.")
|
|
|
|
(defvar sr-speedbar-last-refresh-dictionary nil
|
|
"The last refresh dictionary record of 'sr-speedbar-refresh'.")
|
|
|
|
(eval-when-compile
|
|
(defvar ecb-activated-window-configuration nil)
|
|
(defun ecb-activate ())
|
|
(defun ecb-deactivate ()))
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Interactive functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;;;###autoload
|
|
(defun sr-speedbar-toggle ()
|
|
"Toggle sr-speedbar window.
|
|
Toggle visibility of sr-speedbar by resizing
|
|
the `sr-speedbar-window' to a minimal width
|
|
or the last width when visible.
|
|
Use this function to create or toggle visibility
|
|
of a speedbar-window. It will be created if necessary."
|
|
(interactive)
|
|
(if (sr-speedbar-exist-p)
|
|
(sr-speedbar-close)
|
|
(sr-speedbar-open)))
|
|
|
|
;;;###autoload
|
|
(defun sr-speedbar-open ()
|
|
"Create `sr-speedbar' window."
|
|
(interactive)
|
|
(if (not (sr-speedbar-exist-p))
|
|
(let ((current-window (selected-window)))
|
|
;; Ensure only one window is there
|
|
;; when `sr-speedbar-delete-windows' is non-nil
|
|
(if sr-speedbar-delete-windows
|
|
(delete-other-windows))
|
|
;; Whether activate `other-window' advice
|
|
;; to skip `sr-speedbar' window when use `other-window'.
|
|
(sr-speedbar-handle-other-window-advice sr-speedbar-skip-other-window-p)
|
|
;; Switch buffer
|
|
(if (sr-speedbar-buffer-exist-p speedbar-buffer)
|
|
(unless (sr-speedbar-window-exist-p sr-speedbar-window)
|
|
(sr-speedbar-get-window))
|
|
(if (<= (sr-speedbar-current-window-take-width) sr-speedbar-width)
|
|
(setq sr-speedbar-width sr-speedbar-default-width))
|
|
(sr-speedbar-get-window) ;get `sr-speedbar' window that split current window
|
|
(setq speedbar-buffer (get-buffer-create sr-speedbar-buffer-name)
|
|
speedbar-frame (selected-frame)
|
|
dframe-attached-frame (selected-frame)
|
|
speedbar-select-frame-method 'attached
|
|
speedbar-verbosity-level 0 ;don't say anything, i don't like ... :)
|
|
speedbar-last-selected-file nil)
|
|
(set-buffer speedbar-buffer)
|
|
(buffer-disable-undo speedbar-buffer) ;make disable in speedbar buffer, otherwise will occur `undo-outer-limit' error
|
|
(speedbar-mode)
|
|
(speedbar-reconfigure-keymaps)
|
|
(speedbar-update-contents)
|
|
(speedbar-set-timer 1)
|
|
;; Add speedbar hook.
|
|
(add-hook 'speedbar-before-visiting-file-hook 'sr-speedbar-before-visiting-file-hook t)
|
|
(add-hook 'speedbar-before-visiting-tag-hook 'sr-speedbar-before-visiting-tag-hook t)
|
|
(add-hook 'speedbar-visiting-file-hook 'sr-speedbar-visiting-file-hook t)
|
|
(add-hook 'speedbar-visiting-tag-hook 'sr-speedbar-visiting-tag-hook t)
|
|
;; Add `kill-buffer-hook'.
|
|
(add-hook 'kill-buffer-hook 'sr-speedbar-kill-buffer-hook) ;add `kill-buffer-hook'
|
|
;; Auto refresh speedbar content
|
|
;; if option `sr-speedbar-auto-refresh' is non-nil
|
|
(sr-speedbar-handle-auto-refresh sr-speedbar-auto-refresh))
|
|
(set-window-buffer sr-speedbar-window (get-buffer sr-speedbar-buffer-name))
|
|
(set-window-dedicated-p sr-speedbar-window t) ;make `sr-speedbar-window' dedicated to speedbar-buffer.
|
|
(select-window current-window))
|
|
(message "`sr-speedbar' window has exist.")))
|
|
|
|
(defun sr-speedbar-close ()
|
|
"Close `sr-speedbar' window and save window width."
|
|
(interactive)
|
|
(if (sr-speedbar-exist-p)
|
|
(let ((current-window (selected-window)))
|
|
;; Remember window width.
|
|
(sr-speedbar-select-window)
|
|
(sr-speedbar-remember-window-width)
|
|
;; Close window.
|
|
(if (and (require 'ecb nil t)
|
|
ecb-activated-window-configuration)
|
|
;; Toggle ECB window when ECB window activated.
|
|
(progn
|
|
(ecb-deactivate)
|
|
(ecb-activate))
|
|
;; Otherwise delete dedicated window.
|
|
(delete-window sr-speedbar-window)
|
|
(if (sr-speedbar-window-exist-p current-window)
|
|
(select-window current-window))))
|
|
(message "`sr-speedbar' window is not exist.")))
|
|
|
|
(defun sr-speedbar-select-window ()
|
|
"Force the windows that contain `sr-speedbar'."
|
|
(interactive)
|
|
(if (sr-speedbar-exist-p)
|
|
(select-window sr-speedbar-window)
|
|
(message "`sr-speedbar' window is not exist.")))
|
|
|
|
(defun sr-speedbar-refresh-turn-on ()
|
|
"Turn on refresh content automatically."
|
|
(interactive)
|
|
(setq sr-speedbar-auto-refresh t)
|
|
(sr-speedbar-handle-auto-refresh sr-speedbar-auto-refresh t))
|
|
|
|
(defun sr-speedbar-refresh-turn-off ()
|
|
"Turn off refresh content automatically."
|
|
(interactive)
|
|
(setq sr-speedbar-auto-refresh nil)
|
|
(sr-speedbar-handle-auto-refresh sr-speedbar-auto-refresh t))
|
|
|
|
(defun sr-speedbar-refresh-toggle ()
|
|
"Toggle refresh content status."
|
|
(interactive)
|
|
(setq sr-speedbar-auto-refresh (not sr-speedbar-auto-refresh))
|
|
(sr-speedbar-handle-auto-refresh sr-speedbar-auto-refresh t))
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; utilise functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
(defun sr-speedbar-exist-p ()
|
|
"Return `non-nil' if `sr-speedbar' is exist.
|
|
Otherwise return nil."
|
|
(and (sr-speedbar-buffer-exist-p speedbar-buffer)
|
|
(sr-speedbar-window-exist-p sr-speedbar-window)))
|
|
|
|
(defun sr-speedbar-window-p ()
|
|
"Return `non-nil' if current window is `sr-speedbar' window.
|
|
Otherwise return nil."
|
|
(equal sr-speedbar-buffer-name (buffer-name (window-buffer))))
|
|
|
|
(defun sr-speedbar-remember-window-width ()
|
|
"Remember window width."
|
|
(let ((win-width (sr-speedbar-current-window-take-width)))
|
|
(if (and (sr-speedbar-window-p)
|
|
(> win-width 1)
|
|
(<= win-width sr-speedbar-max-width))
|
|
(setq sr-speedbar-width win-width))))
|
|
|
|
(defun sr-speedbar-get-window ()
|
|
"Get `sr-speedbar' window."
|
|
(setq sr-speedbar-window
|
|
(split-window (selected-window)
|
|
(- sr-speedbar-width)
|
|
(if sr-speedbar-right-side 'right 'left))))
|
|
|
|
(defun sr-speedbar-before-visiting-file-hook ()
|
|
"Function that hook `speedbar-before-visiting-file-hook'."
|
|
(select-window (get-mru-window)))
|
|
|
|
(defun sr-speedbar-before-visiting-tag-hook ()
|
|
"Function that hook `speedbar-before-visiting-tag-hook'."
|
|
(select-window (get-mru-window)))
|
|
|
|
(defun sr-speedbar-visiting-file-hook ()
|
|
"Function that hook `speedbar-visiting-file-hook'."
|
|
(select-window (get-mru-window)))
|
|
|
|
(defun sr-speedbar-visiting-tag-hook ()
|
|
"Function that hook `speedbar-visiting-tag-hook'."
|
|
(select-window (get-mru-window)))
|
|
|
|
(defun sr-speedbar-kill-buffer-hook ()
|
|
"Function that hook `kill-buffer-hook'."
|
|
(when (eq (current-buffer) speedbar-buffer)
|
|
(setq speedbar-frame nil
|
|
dframe-attached-frame nil
|
|
speedbar-buffer nil)
|
|
(speedbar-set-timer nil)
|
|
(remove-hook 'speedbar-before-visiting-file-hook 'sr-speedbar-before-visiting-file-hook)
|
|
(remove-hook 'speedbar-before-visiting-tag-hook 'sr-speedbar-before-visiting-tag-hook)
|
|
(remove-hook 'speedbar-visiting-file-hook 'sr-speedbar-visiting-file-hook)
|
|
(remove-hook 'speedbar-visiting-tag-hook 'sr-speedbar-visiting-tag-hook)))
|
|
|
|
(defun sr-speedbar-refresh ()
|
|
"Refresh the context of speedbar."
|
|
(when (and (not (equal default-directory sr-speedbar-last-refresh-dictionary)) ;if directory is change
|
|
(not (sr-speedbar-window-p))) ;and is not in speedbar buffer
|
|
(setq sr-speedbar-last-refresh-dictionary default-directory)
|
|
(speedbar-refresh)))
|
|
|
|
(defun sr-speedbar-handle-auto-refresh (activate &optional echo-show)
|
|
"Automatically refresh speedbar content when changed directory.
|
|
Do nothing if option ACTIVATE is nil.
|
|
Will display message if ECHO-SHOW is non-nil."
|
|
(if activate
|
|
(progn
|
|
(add-hook 'speedbar-timer-hook 'sr-speedbar-refresh)
|
|
(if echo-show (message "Turn on speedbar content refresh automatically.")))
|
|
(remove-hook 'speedbar-timer-hook 'sr-speedbar-refresh)
|
|
(if echo-show (message "Turn off speedbar content refresh automatically."))))
|
|
|
|
(defun sr-speedbar-current-window-take-width (&optional window)
|
|
"Return the width that WINDOW take up.
|
|
If WINDOW is nil, get current window."
|
|
(let ((edges (window-edges window)))
|
|
(- (nth 2 edges) (nth 0 edges))))
|
|
|
|
(defun sr-speedbar-window-dedicated-only-one-p ()
|
|
"Only have one non-dedicated window."
|
|
(interactive)
|
|
(let ((window-number 0)
|
|
(dedicated-window-number 0))
|
|
(walk-windows
|
|
(lambda (w)
|
|
(with-selected-window w
|
|
(incf window-number)
|
|
(if (window-dedicated-p w)
|
|
(incf dedicated-window-number)))))
|
|
(if (and (> dedicated-window-number 0)
|
|
(= (- window-number dedicated-window-number) 1))
|
|
t nil)))
|
|
|
|
(defun sr-speedbar-window-exist-p (window)
|
|
"Return `non-nil' if WINDOW is exist.
|
|
Otherwise return nil."
|
|
(and window (window-live-p window)))
|
|
|
|
(defun sr-speedbar-buffer-exist-p (buffer)
|
|
"Return `non-nil' if BUFFER is exist.
|
|
Otherwise return nil."
|
|
(and buffer (buffer-live-p buffer)))
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Advices ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
(defadvice delete-other-windows (around sr-speedbar-delete-other-window-advice activate)
|
|
"This advice to make `sr-speedbar' window can't deleted by command `delete-other-windows'."
|
|
(let ((sr-speedbar-active-p (sr-speedbar-window-exist-p sr-speedbar-window)))
|
|
(if sr-speedbar-active-p
|
|
(let ((current-window (selected-window)))
|
|
(dolist (win (window-list))
|
|
(when (and (window-live-p win)
|
|
(not (eq current-window win))
|
|
(not (window-dedicated-p win)))
|
|
(delete-window win))))
|
|
ad-do-it)))
|
|
|
|
(defadvice delete-window (before sr-speedbar-delete-window-advice activate)
|
|
"This advice to remember `sr-speedbar' window width before deleted.
|
|
Use `delete-window' delete `sr-speedbar' window have same effect as `sr-speedbar-close'."
|
|
;; Remember window width before deleted.
|
|
(sr-speedbar-remember-window-width))
|
|
|
|
(defadvice pop-to-buffer (before sr-speedbar-pop-to-buffer-advice activate)
|
|
"This advice is to fix `pop-to-buffer' problem with dedicated window.
|
|
Default, function `display-buffer' can't display buffer in select window
|
|
if current window is `dedicated'.
|
|
|
|
So function `display-buffer' conflict with `sr-speedbar' window, because
|
|
`sr-speedbar' window is `dedicated' window.
|
|
|
|
That is to say, when current frame just have one `non-dedicated' window,
|
|
any functions that use `display-buffer' can't split windows
|
|
to display buffer, even option `pop-up-windows' is enable.
|
|
|
|
And the example function that can occur above problem is `pop-to-buffer'."
|
|
(when (and pop-up-windows ;`pop-up-windows' is enable
|
|
(sr-speedbar-window-dedicated-only-one-p) ;just have one `non-dedicated' window
|
|
(sr-speedbar-window-exist-p sr-speedbar-window)
|
|
(not (sr-speedbar-window-p)) ;not in `sr-speedbar' window
|
|
(not (bound-and-true-p helm-alive-p)))
|
|
(split-window-vertically)
|
|
(windmove-down)))
|
|
|
|
(defadvice other-window (after sr-speedbar-other-window-advice)
|
|
"Default, can use `other-window' select window in cyclic ordering of windows.
|
|
But sometimes we don't want select `sr-speedbar' window use `other-window'.
|
|
Just want make `sr-speedbar' window as a view sidebar.
|
|
|
|
This advice can make `other-window' skip `sr-speedbar' window."
|
|
(let ((count (or (ad-get-arg 0) 1)))
|
|
(when (and (sr-speedbar-window-exist-p sr-speedbar-window)
|
|
(eq sr-speedbar-window (selected-window)))
|
|
(other-window count))))
|
|
|
|
(provide 'sr-speedbar)
|
|
|
|
;;; sr-speedbar.el ends here
|
|
#+end_src
|
|
|
|
*** Speedbar options
|
|
#+begin_src emacs-lisp
|
|
(setq
|
|
speedbar-show-unknown-files t
|
|
sr-speedbar-right-side nil)
|
|
|
|
(global-set-key (kbd "C-x C-n") 'sr-speedbar-toggle)
|
|
#+end_src
|
|
|
|
** Elpher
|
|
|
|
Elpher is a nice little gemini / gopher client.
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package elpher)
|
|
#+end_src
|
|
|
|
* Language Configs
|
|
** Ada
|
|
#+begin_src emacs-lisp
|
|
;;(use-package ada-mode)
|
|
#+end_src
|
|
** Go configuration
|
|
*** go-add-tags
|
|
|
|
This lets one select a ~struct~ or similar and auto add the ~`json:"NAME"`~ bits.
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package go-add-tags
|
|
:bind
|
|
("C-c t" . go-add-tags))
|
|
#+end_src
|
|
|
|
*** go-mode
|
|
|
|
This allows for things like ~gofmt~ and auto adding / removing of imports.
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package go-mode
|
|
:after (go-add-tags lsp-mode)
|
|
:bind
|
|
("C-c t" . go-add-tags))
|
|
(defun lsp-go-install-save-hooks ()
|
|
(add-hook 'before-save-hook #'lsp-format-buffer t t)
|
|
(add-hook 'before-save-hook #'lsp-organize-imports t t))
|
|
(add-hook 'go-mode-hook #'lsp-go-install-save-hooks)
|
|
#+end_src
|
|
|
|
*** go-eldoc
|
|
|
|
This extends eldoc to be able to speak Go - quite handy for quickly looking
|
|
up what things do.
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package go-eldoc
|
|
:after (go-mode lsp-mode)
|
|
:hook
|
|
(go-mode . go-eldoc-setup))
|
|
#+end_src
|
|
|
|
*** yasnippet
|
|
|
|
Some go tools use this.
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package yasnippet
|
|
:commands yas-minor-mode
|
|
:hook (go-mode . yas-minor-mode))
|
|
#+end_src
|
|
|
|
** Zig configuration
|
|
#+begin_src emacs-lisp
|
|
(use-package zig-mode)
|
|
#+end_src
|
|
|
|
** Lua
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package lua-mode)
|
|
#+end_src
|
|
* Mail
|
|
~mu~ has been the best mail client for me on emacs.
|
|
|
|
** Initializing mu
|
|
|
|
The defaults ~mu~ uses make no sense. ~~/.cache~ is for .. caching data, not
|
|
persistent databases.. So we init things with sane defaults:
|
|
|
|
#+begin_src shell
|
|
mu init --muhome=/home/qbit/.mu -m /home/qbit/Maildir/fastmail/ --my-address="aaron@bolddaemon.com"
|
|
#+end_src
|
|
|
|
** General mail configuration
|
|
|
|
#+begin_src emacs-lisp
|
|
(require 'smtpmail)
|
|
(setq user-mail-address "aaron@bolddaemon.com"
|
|
user-full-name "Aaron Bieber"
|
|
message-send-mail-function 'smtpmail-send-it
|
|
message-kill-buffer-on-exit t
|
|
smtpmail-smtp-user "qbit@fastmail.com"
|
|
smtpmail-smtp-server "smtp.fastmail.com"
|
|
smtpmail-smtp-service 465
|
|
smtpmail-default-smtp-server "smtp.fastmail.com"
|
|
smtpmail-stream-type 'ssl)
|
|
#+end_src
|
|
|
|
** mu4e specific configs
|
|
#+begin_src emacs-lisp
|
|
;;(require 'mu4e)
|
|
;;(require 'mu4e-speedbar)
|
|
;;(require 'org-mu4e)
|
|
;;(setq mail-user-agent 'mu4e-user-agent
|
|
;; mu4e-get-mail-command "mbsync fastmail"
|
|
;; mu4e-update-interval 420
|
|
;; mu4e-compose-context-policy nil
|
|
;; mu4e-context-policy 'pick-first
|
|
;; mu4e-drafts-folder "/Drafts"
|
|
;; mu4e-sent-folder "/Sent Items"
|
|
;; mu4e-trash-folder "/Trash"
|
|
;; mu4e-maildir-shortcuts
|
|
;; '( ("/INBOX" . ?i)
|
|
;; ("/Archive" . ?a)
|
|
;; ("/Sent Items" . ?s))
|
|
;; org-mu4e-link-query-in-headers-mode nil
|
|
;; mu4e-attachment-dir
|
|
;; (lambda (fname mtype)
|
|
;; (cond
|
|
;; ((and fname (string-match "\\.diff$" fname)) "~/patches")
|
|
;; ((and fname (string-match "\\.patch$" fname)) "~/patches")
|
|
;; ((and fname (string-match "\\.diff.gz$" fname)) "~/patches")
|
|
;; (t "~/Downloads")))
|
|
;; mu4e-bookmarks
|
|
;; `(( :name "Inbox"
|
|
;; :query "maildir:/Inbox AND NOT flag:trashed"
|
|
;; :key ?i)
|
|
;; ( :name "TODO"
|
|
;; :query "maildir:/TODO AND NOT flag:trashed"
|
|
;; :key ?T)
|
|
;; ( :name "Unread messages"
|
|
;; :query "flag:unread AND NOT flag:trashed AND NOT list:ports-changes.openbsd.org AND NOT list:source-changes.openbsd.org"
|
|
;; :key ?u)
|
|
;; ( :name "Today's messages"
|
|
;; :query (concat
|
|
;; "date:today..now"
|
|
;; " AND NOT flag:trashed"
|
|
;; " AND NOT list:ports-changes.openbsd.org"
|
|
;; " AND NOT list:source-changes.openbsd.org")
|
|
;; :key ?d)
|
|
;; ( :name "Last 7 days"
|
|
;; :query (concat
|
|
;; "date:6d..now"
|
|
;; " AND NOT flag:trashed"
|
|
;; " AND NOT list:ports-changes.openbsd.org"
|
|
;; " AND NOT list:source-changes.openbsd.org")
|
|
;; :key ?w)
|
|
;; ( :name "Hackers"
|
|
;; :query "list:hackers.openbsd.org AND NOT flag:trashed"
|
|
;; :key ?h)
|
|
;; ( :name "Bugs"
|
|
;; :query "list:bugs.openbsd.org AND NOT flag:trashed"
|
|
;; :key ?b)
|
|
;; ( :name "Tech"
|
|
;; :query "list:tech.openbsd.org AND NOT flag:trashed"
|
|
;; :key ?t)
|
|
;; ( :name "Ports"
|
|
;; :query "list:ports.openbsd.org AND NOT flag:trashed"
|
|
;; :key ?p)
|
|
;; ( :name "Misc"
|
|
;; :query "list:misc.openbsd.org AND NOT flag:trashed"
|
|
;; :key ?m)
|
|
;; ( :name "9front"
|
|
;; :query "list:9front.9front.org AND NOT flag:trashed"
|
|
;; :key ?9)
|
|
;; ( :name "GOT"
|
|
;; :query "list:gameoftrees.openbsd.org AND NOT flag:trashed"
|
|
;; :key ?g)))
|
|
#+end_src
|
|
|
|
* org-mode
|
|
|
|
Oh ~org-mode~. It's the reason I started using emacs.. and it's the reason I
|
|
can't quit!
|
|
|
|
** Config
|
|
#+begin_src emacs-lisp
|
|
(org-babel-do-load-languages
|
|
'org-babel-load-languages
|
|
'((plantuml . t)
|
|
(dot . t)
|
|
(latex . t)))
|
|
#+end_src
|
|
** Publish bits
|
|
|
|
I publish some of my notes [[https://suah.dev/p][on suah.dev/p]]. Also some recipes.
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq my-org-publish-alist
|
|
'(("notes" :components ("org-notes" "notes-static" "notes-rss"))
|
|
("deftly" :components ("deftly-blog" "deftly-static"))
|
|
("ohmyksh" :components ("ohmy-web" "ohmy-static"))
|
|
("org-notes"
|
|
:auto-preamble t
|
|
:auto-sitemap t
|
|
:headline-levels 4
|
|
:publishing-directory "/ssh:suah.dev:/var/www/suah.dev/p/"
|
|
:publishing-function org-html-publish-to-html
|
|
:recursive t
|
|
:section-numbers nil
|
|
:html-head "<link rel=\"stylesheet\" href=\"https://suah.dev/p/css/stylesheet.css\" type=\"text/css\" />"
|
|
:html-link-home "http://suah.dev/p/"
|
|
:html-link-up "../"
|
|
:style-include-default nil
|
|
:sitemap-filename "index.org"
|
|
:sitemap-title "Notes"
|
|
:with-title t
|
|
:author-info nil
|
|
:creator-info nil
|
|
:base-directory "~/org/notes")
|
|
("deftly-blog"
|
|
:auto-preamble t
|
|
:auto-sitemap t
|
|
:headline-levels 1
|
|
:publishing-directory "/ssh:suah.dev:/var/www/deftly.net/new/"
|
|
:publishing-function org-html-publish-to-html
|
|
:recursive t
|
|
:section-numbers nil
|
|
:html-head "<link rel=\"stylesheet\" href=\"https://deftly.net/new/css/stylesheet.css\" type=\"text/css\" />"
|
|
:html-link-home "http://deftly.net/new"
|
|
:html-link-up "../"
|
|
:style-include-default nil
|
|
:sitemap-title "Deftly.net"
|
|
:with-title t
|
|
:author-info t
|
|
:creator-info nil
|
|
:base-directory "~/org/deftly")
|
|
("ohmy-web"
|
|
:auto-preamble t
|
|
:auto-sitemap nil
|
|
:headline-levels 2
|
|
:publishing-directory "/ssh:suah.dev:/var/www/deftly.net/ohmyksh/"
|
|
:publishing-function org-html-publish-to-html
|
|
:recursive t
|
|
:section-numbers nil
|
|
:html-head "<link rel=\"stylesheet\" href=\"https://deftly.net/ohmyksh/css/stylesheet.css\" type=\"text/css\" />"
|
|
:html-link-home "http://deftly.net/ohmyksh"
|
|
:html-link-up "../"
|
|
:style-include-default nil
|
|
:with-title t
|
|
:author-info t
|
|
:creator-info nil
|
|
:base-directory "~/src/ohmyksh")
|
|
("notes-static"
|
|
:base-directory "~/org/notes"
|
|
:publishing-directory "/ssh:suah.dev:/var/www/suah.dev/p/"
|
|
:base-extension "css\\|js\\|png\\|jpg\\|gif\\|pdf\\|mp3\\|ogg\\|svg"
|
|
:recursive t
|
|
:publishing-function org-publish-attachment)
|
|
("deftly-static"
|
|
:base-directory "~/org/deftly"
|
|
:publishing-directory "/ssh:suah.dev:/var/www/deftly.net/new/"
|
|
:base-extension "css\\|js\\|png\\|jpg\\|gif\\|pdf\\|mp3\\|ogg"
|
|
:recursive t
|
|
:publishing-function org-publish-attachment)
|
|
("ohmy-static"
|
|
:base-directory "~/src/ohmyksh"
|
|
:publishing-directory "/ssh:suah.dev:/var/www/deftly.net/ohmyksh/"
|
|
:base-extension "css\\|js\\|png\\|jpg\\|gif\\|pdf\\|mp3\\|ogg"
|
|
:recursive t
|
|
:publishing-function org-publish-attachment)
|
|
("notes-rss"
|
|
:publishing-directory "/ssh:suah.dev:/var/www/suah.dev/p/"
|
|
:publishing-function org-rss-publish-to-rss
|
|
:recursive t
|
|
:rss-extension "xml"
|
|
:section-numbers nil
|
|
:exclude ".*"
|
|
:include ("index.org")
|
|
:table-of-contents nil
|
|
:base-directory "~/org/notes")
|
|
("mammoth"
|
|
:publishing-directory "/ssh:suah.dev:/var/www/mammothcircus.com/"
|
|
:publishing-function org-html-publish-to-html
|
|
:author-info nil
|
|
:creator-info nil
|
|
:section-numbers nil
|
|
:recursive t
|
|
:base-directory "~/org/mammoth")
|
|
("recipes"
|
|
:auto-preamble t
|
|
:auto-sitemap t
|
|
:headline-levels 4
|
|
:publishing-directory "/ssh:suah.dev:/var/www/suah.dev/recipes/"
|
|
:publishing-function org-html-publish-to-html
|
|
:recursive t
|
|
:section-numbers nil
|
|
:html-head "<link rel=\"stylesheet\" href=\"https://suah.dev/p/css/stylesheet.css\" type=\"text/css\" />"
|
|
:html-link-home "http://suah.dev/recipes/"
|
|
:html-link-up "../"
|
|
:style-include-default nil
|
|
:sitemap-filename "index.org"
|
|
:sitemap-title "Recipes"
|
|
:with-title t
|
|
:author-info nil
|
|
:creator-info nil
|
|
:base-directory "~/org/recipes")
|
|
))
|
|
#+end_src
|
|
|
|
** Capture templates
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq my-org-capture-templates
|
|
`(("t" "TODO"
|
|
entry (file+headline "~/org/todo.org" "TODOs")
|
|
,(concat
|
|
"* TODO %?\n"
|
|
":PROPERTIES:\n"
|
|
":LOGGING: TODO(!) WAIT(!) DONE(!) CANCELED(!)\n"
|
|
":END:\n") :prepend t)
|
|
("f" "TODO with File"
|
|
entry (file+headline "~/org/todo.org" "TODOs")
|
|
,(concat
|
|
"* TODO %?\n"
|
|
":PROPERTIES:\n"
|
|
":LOGGING: TODO(!) WAIT(!) DONE(!) CANCELED(!)\n"
|
|
":END:\n"
|
|
"%i\n %a") :prepend t)
|
|
("b" "Bug"
|
|
entry (file+olp+datetree "~/org/bugs.org" "Bugs")
|
|
"* BUG %?\nEntered on %U\n :PROPERTIES:\n :FILE: %a\n :END:\n" :prepend t)
|
|
("p" "Protocol"
|
|
entry (file+headline "~/org/links.org" "Links")
|
|
"* %^{Title}\nSource: %u, %c\n #+BEGIN_QUOTE\n%i\n#+END_QUOTE\n\n\n%?")
|
|
("L" "Protocol Link" entry (file+headline "~/org/links.org" "Links")
|
|
"* %? %:link\n%:description\n")
|
|
("j" "Journal"
|
|
entry (file+olp+datetree "~/org/journal.org")
|
|
"* %?\nEntered on %U\n %i\n")))
|
|
#+end_src
|
|
|
|
** org
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package org
|
|
:hook
|
|
(org-mode . (lambda ()
|
|
(turn-on-flyspell)
|
|
(auto-revert-mode)
|
|
(auto-fill-mode 1)))
|
|
:bind
|
|
("C-c c" . org-capture)
|
|
("C-c p" . org-publish)
|
|
("C-c l" . org-store-link)
|
|
("C-c a" . org-agenda)
|
|
("C-c b" . org-iswitchb)
|
|
:config
|
|
(load-library "find-lisp")
|
|
(setq org-directory "~/org"
|
|
org-agenda-files (find-lisp-find-files "~/org" "\.org$")
|
|
org-startup-indented t
|
|
org-log-done 'time
|
|
org-export-with-sub-superscripts nil
|
|
org-html-inline-images t
|
|
org-log-into-drawer t
|
|
org-src-tab-acts-natively t
|
|
org-agenda-skip-scheduled-if-deadline-is-shown t
|
|
org-todo-keywords '((sequence "TODO(t)" "|" "DONE(d)")
|
|
(sequence "REPORT(r)" "BUG(b)" "KNOWNCAUSE(k)" "|" "FIXED(f)")
|
|
(sequence "|" "CANCELED(c)")))
|
|
(setq org-publish-project-alist my-org-publish-alist)
|
|
(setq org-capture-templates my-org-capture-templates))
|
|
|
|
#+end_src
|
|
|
|
** Extra bits
|
|
#+begin_src emacs-lisp
|
|
(use-package org-journal
|
|
:defer t
|
|
:config
|
|
(setq org-journal-dir "~/org/journal/"
|
|
org-journal-file-format "%Y/%m-%d"
|
|
org-journal-date-format "%A, %d %B %Y"))
|
|
#+end_src
|
|
|
|
Add in some org-mode helpers:
|
|
|
|
- ~org-habit~ lets me keep track of TODOs and other things.
|
|
- ~org-checklist~ lets me reset checklists for reoccurring tasks.
|
|
- This requires one to ~pkg_add a2ps~.
|
|
- ~RESET_CHECK_BOXES~ property to be set to ~t~ on a task
|
|
headline. (properties can be set via ~C-c C-x d~
|
|
#+begin_src emacs-lisp
|
|
(require 'org-habit)
|
|
;(require 'org-checklist)
|
|
#+end_src
|
|
|
|
Found this bad boy to integrate pinboard with org-mode:
|
|
- https://gist.github.com/khinsen/7ed357eed9b27f142e4fa6f5c4ad45dd
|
|
#+begin_src emacs-lisp
|
|
(defun org-pinboard-store-link ()
|
|
"Store a link taken from a pinboard buffer."
|
|
(when (eq major-mode 'pinboard-mode)
|
|
(pinboard-with-current-pin pin
|
|
(org-store-link-props
|
|
:type "pinboard"
|
|
:link (alist-get 'href pin)
|
|
:description (alist-get 'description pin)))))
|
|
|
|
(org-link-set-parameters "pinboard"
|
|
:follow #'browse-url
|
|
:store #'org-pinboard-store-link)
|
|
#+end_src
|
|
|
|
Custom agenda commands for various things.
|
|
|
|
- ~Daily habits~ shows how well I am keeping track of daily things.
|
|
#+begin_src emacs-lisp
|
|
(setq org-agenda-custom-commands
|
|
'(("h" "Daily habits"
|
|
((agenda ""))
|
|
((org-agenda-show-log t)
|
|
(org-agenda-ndays 7)
|
|
(org-agenda-log-mode-items '(state))))))
|
|
#+end_src
|
|
|
|
** GOT
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq vc-got-dir (expand-file-name "~/.emacs.d/site-lisp/vc-got-1.0"))
|
|
(if (file-directory-p vc-got-dir)
|
|
(use-package vc-got
|
|
:load-path vc-got-dir
|
|
:defer t
|
|
:init
|
|
(add-to-list 'vc-handled-backends 'Got)
|
|
(add-to-list 'vc-directory-exclusion-list ".got")))
|
|
#+end_src
|