Skip to content
Permalink
Branch: master
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
4653 lines (3750 sloc) 152 KB

bba emacs configuration

Configuration

<<babel-init>>

Inspired by the Emacs Starter Kit and Sacha Chua I set up my configuration file using Org-babel. You could load it with (org-babel-load-file "/path/to/file"), changing the path appropriately, but you’ll probably want to tweak it extensively first.

Some general links regarding these configuration:

To be precise, this is what’s in the first part of my ~/.emacs.d/init.el (what used to be the ~/.emacs file):

;; This sets up the load path so that we can override it
;; (package-initialize)
;; Override the packages with the git version of Org and other packages

  (setq load-path
  (append
  (list (expand-file-name "~/.emacs.d/") (expand-file-name "~/.emacs.d/elpa/org-20150629"))
  ;;           (expand-file-name "/usr/share/emacs/lisp/")
  load-path))


(add-to-list 'load-path "~/.emacs/elpa/org-20171030")

;; (add-to-list 'load-path "~/elisp/org-mode/contrib/lisp")
;; Load the rest of the packages
;; (package-initialize t)
;; (setq package-enable-at-startup nil)
(setq org-use-extra-keys t)
(require 'org)
(require 'ob-tangle)
(require 'ob-sql)
(require 'ob-async)
(org-babel-load-file (expand-file-name "~/.emacs.d/bba.org"))

This git repository includes a .gitignore file excluding .elc files. You might want to run C-u 0 M-x byte-recompile-directory after a fresh clone. Install the githooks and your .elc files will get recompiled after a git pull.

debugging

If you are in need enable debugging:

(setq debug-on-error t)

run in servermode

(require 'server)
(unless (server-running-p)
  (server-start))

welcome screen

No need for that:

(setq inhibit-startup-screen t)

shell aliases

Some aliases you might want to set in your bash to talk to your Emacs server:

alias e='emacsclient -n -a emacs'
alias magit='emacsclient -n -e "(magit-status \"$(pwd)\")"'
alias eshell='emacsclient -n -e "(eshell-client)"'

set environment variables on osx

[2015-07-16 Thu 19:10]

If running standalone on OSX we need to get some environment variables from bash.

(setenv "EDITOR" "emacsclient")

(if (string-equal system-type "darwin")
        (progn
          (let ((path (shell-command-to-string ". ~/.bashrc >/dev/null; echo -n $PATH")))
            (setenv "PATH" path)
            (setq exec-path
                  (append
                   (split-string-and-unquote path ":")
                   exec-path)))
          (let ((path (shell-command-to-string ". ~/.bashrc >/dev/null; echo -n $LANG")))
            (setenv "LANG" path)
            )
          (let ((path (shell-command-to-string ". ~/.bashrc >/dev/null; echo -n $EMAIL")))
            (setenv "EMAIL" path)
            )
          (let ((path (shell-command-to-string ". ~/.bashrc >/dev/null; echo -n $ORGANIZATION")))
            (setenv "ORGANIZATION" path)
            )
          (let ((path (shell-command-to-string ". ~/.bashrc >/dev/null; echo -n $GOPATH")))
            (setenv "GOPATH" path)
            )
          (let ((path (shell-command-to-string ". ~/.bashrc >/dev/null; echo -n $PYTHONPATH")))
            (setenv "PYTHONPATH" path)
            )
          (let ((path (shell-command-to-string ". ~/.bashrc >/dev/null; echo -n $SSH_AUTH_SOCK")))
            (setq ssh-auth-sock path)
            (setenv "SSH_AUTH_SOCK" path)
            )
          (let ((path (shell-command-to-string ". ~/.bashrc >/dev/null; pidof ssh-agent | tr -d ' \n'")))
            (setenv "SSH_AGENT_PID" path)
            )
          (let ((path (shell-command-to-string ". ~/.bashrc >/dev/null; echo -n $GPG_AGENT_INFO")))
            (setenv "GPG_AGENT_INFO" path)
            )
          (let ((path (shell-command-to-string ". ~/.bashrc >/dev/null; echo -n $ORACLE_HOME")))
            (setenv "ORACLE_HOME" path)
            )
          (let ((path (shell-command-to-string ". ~/.bashrc >/dev/null; echo -n $CLASSPATH")))
            (setenv "CLASSPATH" path)
            )
          (let ((path (shell-command-to-string ". ~/.bashrc >/dev/null; echo -n $NLS_LANG")))
            (setenv "NLS_LANG" path)
            )
          (let ((path (shell-command-to-string ". ~/.bashrc >/dev/null; echo -n $TNS_ADMIN")))
            (setenv "TNS_ADMIN" path)
            )
          (let ((path (shell-command-to-string ". ~/.bashrc >/dev/null; echo -n $DYLD_LIBRARY_PATH")))
            (setenv "DYLD_LIBRARY_PATH" path)
            )
          (let ((path (shell-command-to-string ". ~/.bashrc >/dev/null; echo -n $SYSENV")))
            (setenv "SYSENV" path)
            )
          (let ((path (shell-command-to-string ". ~/.bashrc >/dev/null; echo -n $http_proxy")))
            (setenv "http_proxy" path)
            )
          (let ((path (shell-command-to-string ". ~/.bashrc >/dev/null; echo -n $https_proxy")))
            (setenv "https_proxy" path)
            )
          )
    )

move files to trash on osx

[2017-02-10 Fri 15:12]

If trash is missing you might want to run

sudo port install trash

 (if (string-equal system-type "darwin")
 (if (file-exists-p "/opt/local/bin/trash")
     (progn
	(defun system-move-file-to-trash (file)
     "Use osx port trash to move files to trash"
     (call-process "trash" nil nil nil file)
	)
     )
 )
 )

With trash you can recover files to it’s original location.

eshell and shell environment

We don’t need a $PAGER in Emacs:

(setenv "PAGER" "cat")

Want to have some shell aliases, right?

(defalias 'e 'find-file)
(defalias 'ff 'find-file)
(defalias 'emacs 'find-file)

Some of my favorite bash aliases, can be even more helpful in Eshell. Like ‘ll’:

(require 'em-alias)
(add-hook 'eshell-mode-hook
          (lambda ()
            ;; The 'ls' executable requires the Gnu version on the Mac
            (let ((ls (if (file-exists-p "/opt/local/bin/gls")
                          "/opt/local/bin/gls"
                        "/bin/ls")))
              (add-to-list 'eshell-command-aliases-list (list "ll" (concat ls " -AlohG --color=always") )))))

What about gd to call the Diff command?

(defalias 'gd 'magit-diff-unstaged)
(defalias 'gds 'magit-diff-staged)

define emacs shutdown function

I like to commit my notes in my org and workorg folders after a days work. Keep track of your important stuff!

;; define function to shutdown emacs server instance
(defun server-shutdown ()
  "Save buffers, Quit, and Shutdown (kill) server"
  (interactive)
  (save-some-buffers)
  (shell-command "git --work-tree ~/org/ --git-dir ~/org/.git commit -a -m 'autocommit'")
  (shell-command "git --work-tree ~/org/ --git-dir ~/org/.git push origin")
  (if (equal "work" (getenv "SYSENV"))
      (progn
        (shell-command "git --work-tree ~/workorg/ --git-dir ~/workorg/.git commit -a -m 'autocommit'")
        (shell-command "git --work-tree ~/workorg/ --git-dir ~/workorg/.git push origin")
        ))
  (setq twittering-cert-file nil)
  (kill-emacs)
  )

async

(if (>= emacs-major-version 24)
    (progn
      (add-to-list 'load-path "~/.emacs.d/elpa/async-20181224.454")
      (require 'async)
      )
  )

ELPA

(if (>= emacs-major-version 24)
    (progn
      (add-to-list 'load-path "~/.emacs.d/elpa")
      (add-to-list 'load-path "~/.emacs.d/elpa/popup-20160709.1429")
      (require 'package)
      (package-initialize)
      (add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/"))
      (add-to-list 'package-archives '("marmalade" . "http://marmalade-repo.org/packages/"))
      (add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/"))
      )
  (progn
    (add-to-list 'load-path "~/.emacs.d/elpa/cl-lib-0.5")
    (add-to-list 'load-path "~/.emacs.d/elpa/magit-1.2.0")
    (add-to-list 'load-path "~/.emacs.d/elpa/yaml-mode-20160220.340")
    (require 'yaml-mode)
    )

  )

magit

For annotated tags prepare message with commit messages since last tag.

(require 'magit)
(setq magit-last-seen-setup-instructions "1.4.0")
(define-key magit-mode-map (kbd "<s-return>") 'ffap)

(add-hook 'git-commit-mode-hook
          (lambda()
            (when (equal "TAG_EDITMSG" (buffer-name))
              (progn
                (insert (shell-command-to-string "git log --pretty=format:\"* %s\" `git rev-list --tags --max-count=1`..HEAD" ))
                (newline)
                (goto-char (point-min))
                (newline)
                (goto-char (point-min))
                )
              )
            )
          )

Display open TODO items in magit-status.

(require 'magit-todos)
(magit-todos-mode)

do a stash, pull, pop. in the end use magit-stash.

(defun bba-pull ()
  "Do git stash, pull, pop"
  (interactive)
  (shell-command "git stash; git pull; git stash pop")
  )

fullframe

open ibuffer and magit-status in fullframe mode.

(if (>= emacs-major-version 25)
    (progn
      (add-to-list 'load-path "~/.emacs.d/elpa/fullframe-20170816.1003")
      (require 'fullframe)
      (fullframe magit-status magit-mode-quit-window)
      )
  )

winner-mode

[2015-06-10 Wed 09:33]

Get undo for your window layout.

(if (>= emacs-major-version 24)
    (winner-mode 1))

smartparens-mode

Enable smart parens in all modes. See Smartparens on github. Some key bindings taken from emacs-pairs.

(if (>= emacs-major-version 24)
    (progn
      (add-to-list 'load-path "~/.emacs.d/elpa/smartparens-20190112.1318")
      (add-to-list 'load-path "~/.emacs.d/elpa/dash-20180910.1856")
      (require 'smartparens)
      (smartparens-global-mode 1)
      (defmacro def-pairs (pairs)
        `(progn
           ,@(cl-loop for (key . val) in pairs
                   collect
                   `(defun ,(read (concat
                                   "wrap-with-"
                                   (prin1-to-string key)
                                   "s"))
                        (&optional arg)
                      (interactive "p")
                      (sp-wrap-with-pair ,val)))))

      (def-pairs ((paren        . "(")
                  (bracket      . "[")
                  (brace        . "{")
                  (single-quote . "'")
                  (double-quote . "\"")
                  (back-quote   . "`")))

      (define-key smartparens-mode-map (kbd "C-'") 'sp-rewrap-sexp)
      (define-key smartparens-mode-map (kbd "C-c (") 'wrap-with-parens)
      (define-key smartparens-mode-map (kbd "C-c ]") 'sp-backward-unwrap-sexp)
      (define-key smartparens-mode-map (kbd "C-c )") 'sp-unwrap-sexp)
      (define-key smartparens-mode-map (kbd "C-c [") 'wrap-with-brackets)
      (define-key smartparens-mode-map (kbd "C-c {") 'wrap-with-braces)
      (define-key smartparens-mode-map (kbd "<C-S-kp-4>") 'sp-beginning-of-sexp)
      (define-key smartparens-mode-map (kbd "<C-S-kp-6>") 'sp-end-of-sexp)
      (define-key smartparens-mode-map (kbd "<C-S-kp-8>") 'sp-up-sexp)
      (define-key smartparens-mode-map (kbd "<C-S-kp-2>") 'sp-down-sexp)
      ))

rainbow-delimiters

Highlight delimiters such as parentheses, brackets or braces according to their depth. But we use it only in graphical mode as text mode lacks color depth.

(if (>= emacs-major-version 24)
    (when (display-graphic-p)
      (add-to-list 'load-path "~/.emacs.d/elpa/rainbow-delimiters-20170929.1132")
      ))

engine-mode

search the web on your fingertips. C-c /.

aamazon.de
bbing
ccfengine
ggoogle
Ggithub
mgoogle maps
ppuppet
vvertica
wwikipedia
yyoutube
(if (>= emacs-major-version 24)
    (progn
      (require 'engine-mode)

      (defengine amazon
        "http://www.amazon.de/s/ref=nb_sb_noss?url=search-alias=aps&filed-keywords=%s"
        :keybinding "a"
        )

      (defengine aws
        "https://docs.aws.amazon.com/search/doc-search.html?searchPath=documentation-guide&searchQuery=%s"
        :keybinding "A"
        )

      (defengine bing
        "http://www.bing.com/search?q=%s&qs=bs&form=QBLH"
        :browser 'eww-browse-url
        :keybinding "b"
        )

      (defengine cfengine
        "https://docs.cfengine.com/latest/search.html?q=%s"
        :browser 'eww-browse-url
        :keybinding "c"
        )


      (defengine github
        "http://www.github.com/search?q=%s"
        :browser 'eww-browse-url
        :keybinding "G"
        )

      (defengine google
        "http://www.google.com/?q=%s"
        :keybinding "g"
        )

      (defengine leo
        "http://dict.leo.org/ende/index_de.html#/search=%s"
        :keybinding "l"
        )

      (defengine google-maps
        "http://maps.google.com/maps?q=%s"
        :keybinding "m"
        )

      (defengine puppet
        "https://puppet.com/search/docs?keys=%s"
        :keybinding "p"
        )

      (defengine vertica
        "https://www.vertica.com/docs/9.2.x/HTML/Content/Search/index.htm?q=%s&page=1&searchIDx=9_2_0-live"
        :keybinding "v"
        )

      (defengine wikipedia
        "http://www.wikipedia.org/search-redirect.php?language=en&go=Go&search=%s"
        :browser 'eww-browse-url
        :keybinding "w"
        )

      (defengine youtube
        "http://www.youtube.com/results?aq=f&oq=&search_query=%s"
        :keybinding "y"
        )
      (engine-mode 1)
      (engine/set-keymap-prefix (kbd "C-c C-/"))
      )
  )

expand-region

[2015-04-02 Thu 10:32]

(if (>= emacs-major-version 24)
    (progn
      (add-to-list 'load-path "~/.emacs.d/elpa/expand-region-20180817.1134")
      (require 'expand-region)
      (define-key global-map (kbd "C-c C-<f12>") 'er/contract-region )
      (define-key global-map (kbd "C-c <f12>") 'er/expand-region )
      ))

yasnippet

My first thought: Nice. But do I have a use case? After half a year I cannot live without it. I write most of my CFEngine code with snippets. Some help for Perl and even for org-mode. Thought about using snippets for shell-mode and eshell-mode? snippets for aws cli are awesome! ha-autoinsert-yas-expand copied from Howard Abrams.

(add-to-list 'load-path
             "~/.emacs.d/elpa/yasnippet-20181015.1212")
(require 'yasnippet)

(if (equal "work" (getenv "SYSENV"))
    (add-to-list 'yas-snippet-dirs "~/workorg/snippets"))
(add-to-list 'yas-snippet-dirs "~/.emacs.d/snippets")
(yas-reload-all)
(yas-global-mode 1)
(setq yas-indent-line nil)
(setq yas-triggers-in-field t)
(auto-insert-mode 1)
(setq auto-insert-directory "~/.emacs.d/templates")
(define-key global-map "\C-cy" 'yas-insert-snippet)
  (if (>= emacs-major-version 24)
      (add-to-list 'yas-prompt-functions 'yas-shk-helm-prompt))
(defun ha-autoinsert-yas-expand()
  "Replace text in yasnippet template."
  (yas-expand-snippet (buffer-string) (point-min) (point-max)))
(define-auto-insert "\\.go$" ["default-go.go" ha-autoinsert-yas-expand])
(define-auto-insert "\\.sh$" ["default-sh.sh" ha-autoinsert-yas-expand])
(define-auto-insert "\\.pl$" ["default-pl.pl" ha-autoinsert-yas-expand])
(define-auto-insert "\\.tex$" ["default-tex.tex" ha-autoinsert-yas-expand])
(define-auto-insert "\\.emacs.d/snippets/[^/]*/" ["default-snippet" ha-autoinsert-yas-expand])

From http://emacswiki.org/emacs/Yasnippet

(if (>= emacs-major-version 24)
    (defun yas-shk-helm-prompt (prompt choices &optional display-fn)
      "Use helm to select a snippet. Put this into `yas/prompt-functions.'"
      (interactive)
      (setq display-fn (or display-fn 'identity))
      (if (require 'helm-config)
          (let (tmpsource cands result rmap)
            (setq cands (mapcar (lambda (x) (funcall display-fn x)) choices))
            (setq rmap (mapcar (lambda (x) (cons (funcall display-fn x) x)) choices))
            (setq tmpsource
                  (list
                   (cons 'name prompt)
                   (cons 'candidates cands)
                   '(action . (("Expand" . (lambda (selection) selection))))
                   ))
            (setq result (helm-other-buffer '(tmpsource) "*helm-select-yasnippet"))
            (if (null result)
                (signal 'quit "user quit!")
              (cdr (assoc result rmap))))
        nil)))

Default to snippet-mode if we are in a sub directory of snippets:

(add-to-list 'auto-mode-alist '("\\.emacs.d/snippets/[^/]*/" . snippet-mode))

define some major modes for yasnippets

[2016-05-25 Wed 10:26]

I use yasnippet for sql a lot. Languages differ and I need different templates.

(define-derived-mode sql-oracle-mode sql-mode "OracleSQL"
  "Major mode for ORACLE SQL"
  (setq sql-product 'oracle)
  )
(define-derived-mode sql-vertica-mode sql-mode "VerticaSQL"
  "Major mode for Vertica"
  (setq sql-product 'ansi)
  )
(define-derived-mode sql-mysql-mode sql-mode "MySQL"
  "Major mode for MySQL"
  (setq sql-product 'mysql)
  )

flycheck

To get puppet-lint:

gem install puppet-lint

modified puppet-lint definition to include no-80chars-check and fixed log-format.

 (if (>= emacs-major-version 24)
     (progn
	(add-to-list 'load-path "~/.emacs.d/elpa/flycheck-20190108.351")
	(require 'flycheck)
	(add-hook 'after-init-hook #'global-flycheck-mode)
	(flycheck-define-checker puppet-lint
         "A Puppet DSL style checker using puppet-lint.

 See URL `http://puppet-lint.com/'."
         ;; We must check the original file, because Puppetlint is quite picky on the
         ;; names of files and there place in the directory structure, to comply with
         ;; Puppet's autoload directory layout.  For instance, a class foo::bar is
         ;; required to be in a file foo/bar.pp.  Any other place, such as a Flycheck
         ;; temporary file will cause an error.
         :command ("puppet-lint"
                   "--no-80chars-check" "--log-format" "%{path}:%{line}:%{kind}: %{message} (%{check})"
                   source-original)
         :error-patterns
         ((warning line-start (file-name) ":" line ":warning: " (message) line-end)
          (error line-start (file-name) ":" line ":error: " (message) line-end))
         :modes puppet-mode
         ;; Since we check the original file, we can only use this syntax checker if
         ;; the buffer is actually linked to a file, and if it is not modified.
         :predicate flycheck-buffer-saved-p)
	))
 (setq puppet-lint-command
	(concat
	 "puppet-lint --with-context "
	 "--no-80chars-check "
	 "--no-puppet_url_without_modules-check "
	 "--fail-on-warnings "
	 "--log-format \"%{path}:%{line}: %{kind}: %{message} (%{check})\""
	 )
	)
(setq flycheck-json-python-json-executable "python2.7")

guide-key

Probably the best help to keep track of the not every day used keybindings.

(if (>= emacs-major-version 24)
    (progn
      (add-to-list 'load-path "~/.emacs.d/elpa/popwin-20150315.1300")
      (add-to-list 'load-path "~/.emacs.d/elpa/guide-key-20150108.635")
      (require 'guide-key)
      (setq guide-key/guide-key-sequence '("C-x" "C-x C-k" "C-x 4" "C-c" "C-h" "C-x l" "<ESC>" "<f9>"))
      (setq guide-key/recursive-key-sequence-flag t)
      (setq guide-key/idle-delay 3)
      (guide-key-mode 1)
      )
  )

hidepw

[2016-02-11 Thu 16:10]

Hide passwords on the screen from shoulder surfing. Single pipes interfere with org tables. Just go double.

(load-file (expand-file-name "~/.emacs.d/lisp/hidepw.el"))
(add-hook 'org-mode-hook  'hidepw-mode)
(setq hidepw-pattern "||\\(.*\\)||")

latex

Use orgtbl to create tables.

(setq tex-dvi-view-command "(f=*; pdflatex \"${f%.dvi}.tex\" && open \"${f%.dvi}.pdf\")")
(setq TeX-auto-save t)
(setq TeX-parse-self t)
(setq-default TeX-master nil)

(add-hook 'latex-mode-hook
  (lambda ()
    (auto-fill-mode)
    (orgtbl-mode)
    ))

thesaurus

  ;; The file names are absolute, not relative, locations
  ;;     - e.g. /foobar/mthesaur.txt.cache, not mthesaur.txt.cache
  (setq synonyms-file        "~/.emacs.d/mthesaur.txt")
  (setq synonyms-cache-file  "~/.emacs.d/mthesaur.txt.cache")
  (require 'synonyms)
;;  (define-key global-map (kbd "C-c ?") 'synonyms)

yaml mode

Adjust indentation at work.

 ;; load yaml-mode
 ;; (require 'yaml-mode)
 ;; (add-to-list 'auto-mode-alist '("\\.yml$" . yaml-mode))
(defvar bba-keep-whitespaces)
(if (equal "work" (getenv "SYSENV"))
    (setq yaml-indent-offset 4))
(add-hook 'yaml-mode-hook
          (lambda()
            (auto-fill-mode -1)
          (setq bba-keep-whitespaces 1)))

highlight indentation

[2016-10-09 Sun 17:13]

(load-file (expand-file-name "~/.emacs.d/lisp/highlight-indentation.el"))
(set-face-background 'highlight-indentation-face "#e3e3d3")
(set-face-background 'highlight-indentation-current-column-face "#c3b3b3")

htmlize

To get syntax highlight for HTML exports:

(if (>= emacs-major-version 24)
    (progn
      (require 'htmlize )
      )
)

vc-git

(require 'vc-git)
  (when (featurep 'vc-git) (add-to-list 'vc-handled-backends 'git))

avy

Replaced the deprecated ace-jump-mode with avy-goto-char and goto-line with avy-goto-line.

(add-to-list 'load-path "~/.emacs.d/elpa/avy-20190122.1420")
(require 'avy)
(define-key global-map (kbd "C-c C-@") 'avy-goto-word-1)
(define-key global-map (kbd "C-c C-SPC") 'avy-goto-word-1)
(define-key global-map (kbd "M-g g") 'avy-goto-line)
(define-key global-map (kbd "C-c C-S-SPC") 'avy-goto-char-timer)

ido-mode

I still like ido-find-file.

(ido-mode t)
(setq ido-enable-prefix nil
      ido-enable-flex-matching t
      ido-case-fold nil
      ido-auto-merge-work-directories-length -1
      ido-create-new-buffer 'always
      ido-use-filename-at-point nil
      ido-max- 10)
;; (require 'ido-vertical-mode)
;; (ido-vertical-mode)

;; (defun sd/ido-define-keys() ;; C-n/p is more intuitive in vertical layout
;;   (define-key ido-completion-map (kbd "C-n") 'ido-next-match)
;;   (define-key ido-completion-map (kbd "<down>") 'ido-next-match)
;;   (define-key ido-completion-map (kbd "C-p") 'ido-prev-match)
;;   (define-key ido-completion-map (kbd "<up>") 'ido-prev-match)
;; )

visual-regexp

(if (>= emacs-major-version 24)
    (progn
      (require 'visual-regexp)
      (define-key global-map (kbd "M-&") 'vr/query-replace)
      (define-key global-map (kbd "M-/") 'vr/replace)
      )
)

org-mode

See orgtutorial_dto for details.

It’s worth to use Emacs for org-mode alone. Literate DevOps and Literate Database Work are only 2 use cases. With org html themes it’s easy to generate beautiful output.

(require 'ox-md nil t)

org-mac-link

[2018-11-06 Tue 14:20]

(if (string-equal system-type "darwin")
    (require 'org-mac-link)
  (define-key org-mode-map (kbd "C-c g") 'org-mac-grab-link))

org-eldoc

[2017-01-06 Fri 14:23]

(load-file (expand-file-name "~/.emacs.d/lisp/org-eldoc.el"))

org-plus-contrib

Some extra functionality from the org package repository.

(if (>= emacs-major-version 24)
    (progn
      (add-to-list 'load-path "~/.emacs.d/elpa/org-plus-contrib-20170407" t)
      ))

org-protocol

Run these commands to make org-protocol work in gnome:

gconftool-2 -s /desktop/gnome/url-handlers/org-protocol/command '/usr/bin/emacsclient %s' --type String
gconftool-2 -s /desktop/gnome/url-handlers/org-protocol/enabled --type Boolean true

this is how your firefox bookmark must look like:

javascript:location.href='org-protocol://capture:/l/'%20+%20encodeURIComponent(location.href)+'/'%20+%20encodeURIComponent(document.title)+%20'/'%20+%20encodeURIComponent(window.getSelection()%20)
(require 'org-protocol)

(add-to-list 'auto-mode-alist '("\\.org$" . org-mode))
(define-key global-map "\C-cl" 'org-store-link)
(define-key global-map "\C-ca" 'org-agenda)
(setq org-log-done t)
(setq org-id-method (quote uuidgen))
(setq org-src-window-setup 'current-window)
(setq org-startup-indented 1)

(if (equal "work" (getenv "SYSENV"))
(setq org-agenda-files (list "~/workorg/work.org"
                             "~/org/notes.org"
                             "~/org/emacs.org"
                             "~/org/private.org"
                             "~/org/it.org"
                             "~/org/refile.org"
                             "~/org/workhours.org"
                             ))
(setq org-agenda-files (list "~/org/work.org"
                             "~/org/notes.org"
                             "~/org/emacs.org"
                             "~/org/private.org"
                             "~/org/it.org"
                             "~/org/refile.org"
                             "~/org/workhours.org"
                             ))
)

ob-applescript

[2016-09-27 Tue 09:34]

This module lets you run AppleScript from AppleScript source code blocks with Org Babel.

This package is a direct result of attempting to answer a question on this emacs.stackexchange.com thread.

(require 'ob-applescript)

ox-jira

[2016-05-22 Sun 20:53]

Org-mode export backend for JIRA markup

(if (>= emacs-major-version 24)
    (require 'ox-jira))

We are lazy and want to speed up things:

(defun bba-org-export-jira-clipboard()
  "narrow to org subtree and store content in jira format in clipboard."
  (interactive)
  (org-narrow-to-subtree)
  (bba-export-jira-org)
  (let ((org-export-use-babel nil))
    (ox-jira-export-as-jira))
  (delete-region (point) (progn (forward-line 1)(point)))
  (push-mark (point))
  (push-mark (point-max) nil t)
  (goto-char (point-min))
  (kill-ring-save 1 1 1)
  (other-window -1)
  (widen)
  (other-window 1)
  )

(define-key org-mode-map "\C-c\S-j" 'bba-org-export-jira-clipboard)

Besides the clipboard we want also an org file in /tmp/ to attach to the jira ticket. Of course some boiler plate for the poor souls who never heard of orgmode.

(defun bba-export-jira-org()
  "export current narrowed view to file in tmp and open a finder window on OS-X."
  (interactive)
  (goto-char (point-min))
  (insert "# This file is just plain text called orgmode")
  (newline)
  (insert "# https://en.wikipedia.org/wiki/Org-mode")
  (newline)
  (insert "# You can open it in any text editor or file reader.")
  (newline)
  (insert "# You might want to use Emacs for best experience.")
  (newline)
  (if (re-search-forward "jira:" nil t 1)
      (if (org-in-regexp org-bracket-link-regexp 1)
          (let ((remove (list (match-beginning 0) (match-end 0)))
                (description (last (split-string (if (match-end 3)
                                                     (match-string-no-properties 3)
                                                   (match-string-no-properties 1)) ":"))))
            (org-open-at-point)
            (push-mark (point))
            (push-mark (point-max) nil t)
            (goto-char (point-min))
            (write-region (mark) (point) (concat "/tmp/" (car description) ".org") nil nil )
            (deactivate-mark)
            (if (string-equal system-type "darwin")(shell-command "open /tmp/"))
            )))
  (goto-char (point-min))
  (kill-line 4)
  )
(defun bba-open-jira()
"open current ticket."
(interactive)
(let ((oldpoint (point-marker)))
(org-narrow-to-subtree)
(goto-char (point-min))
(if (re-search-forward "jira:" nil t 1)
    (org-open-at-point)
  (progn (widen)
          (outline-up-heading 1 t)
          (bba-open-jira)
))
(widen)
(goto-char oldpoint)
)
)

(define-key org-mode-map "\C-xl\S-j" 'bba-open-jira)

ox-reveal

[2017-11-06 Mon 23:26]

Get reveal.js as well:

git clone https://github.com/hakimel/reveal.js/
(require 'ox-reveal)

ox-publish

[2018-01-24 Wed 20:29]

(require 'ox-html)
(require 'ox-publish)
(require 'ox-rss)
(require 'htmlize)
(setq org-mode-websrc-directory (concat (getenv "HOME") "/git/website/org"))
(setq org-mode-publishing-directory (concat (getenv "HOME") "/git/website/html/"))

(setq org-publish-project-alist
      `(("all"
         :components ("blog-content" "blog-static" "blog-rss"))

        ("blog-content"
         :base-directory       ,org-mode-websrc-directory
         :base-extension       "org"
         :publishing-directory ,org-mode-publishing-directory
         :recursive            t
         :publishing-function  org-html-publish-to-html
;         :preparation-function org-mode-blog-prepare
         :export-with-tags     nil
         :headline-levels      4
         :auto-preamble        t
         :auto-postamble       nil
         :auto-sitemap         t
         :sitemap-title        "Bundesbrandschatzamt"
         :section-numbers      nil
         :table-of-contents    nil
         :with-toc             nil
         :with-author          nil
         :with-creator         nil
         :with-tags            t
         :with-smart-quotes    t

         :html-doctype         "html5"
         :html-html5-fancy     t
         :html-preamble        org-mode-blog-preamble
         :html-postamble       org-mode-blog-postamble
         :html-head  "<link href='http://fonts.googleapis.com/css?family=Source+Sans+Pro:400,700&subset=latin,latin-ext' rel='stylesheet' type='text/css'>
            <link href='http://fonts.googleapis.com/css?family=Source+Serif+Pro:400,700&subset=latin,latin-ext' rel='stylesheet' type='text/css'>
            <link href='http://fonts.googleapis.com/css?family=Source+Code+Pro:400,700' rel='stylesheet' type='text/css'>
            <link rel=\"stylesheet\" href=\"/~baron/css/styles.css\" type=\"text/css\"/>\n"
         :html-head-extra "<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js\"></script>
            <script src=\"/~baron/js/magic.js\"></script>
            <link rel=\"icon\" href=\"/~baron/img/dragon.svg\">
            <link rel=\"shortcut icon\" href=\"~baron/img/dragon-head.png\">
            <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />"
         :html-head-include-default-style nil
         )

        ("blog-static"
         :base-directory       ,org-mode-websrc-directory
         :base-extension       "css\\|js\\|png\\|jpg\\|gif\\|pdf\\|mp3\\|ogg\\|swf\\|svg"
         :publishing-directory ,org-mode-publishing-directory
         :recursive            t
         :publishing-function  org-publish-attachment
         )

        ("blog-rss"
         :base-directory        ,org-mode-websrc-directory
         :base-extension        "org"
         :rss-image-url         "http://www.bundesbrandschatzamt.de/~baron/img/dragon-head.png"
         :publishing-directory  ,org-mode-publishing-directory
         :publishing-function   (org-rss-publish-to-rss)
         :html-link-home        "http://www.bundesbrandschatzamt.de/~baron/"
         :html-link-use-abs-url t
         :with-toc              nil
         :exclude               ".*"
         :include               ("index.org"))))

(defun org-mode-blog-preamble (options)
  "The function that creates the preamble top section for the blog.
OPTIONS contains the property list from the org-mode export."
  (let ((base-directory (plist-get options :base-directory)))
    (org-babel-with-temp-filebuffer (expand-file-name "top-bar.html" base-directory) (buffer-string))))

(defun org-mode-blog-postamble (options)
  "The function that creates the postamble, or bottom section for the blog.
OPTIONS contains the property list from the org-mode export."
  (let ((base-directory (plist-get options :base-directory)))
    (org-babel-with-temp-filebuffer (expand-file-name "bottom.html" base-directory) (buffer-string))))

(defun org-mode-blog-prepare ()
  "`index.org' should always be exported so touch the file before publishing."
  (let* ((base-directory (plist-get project-plist :base-directory))
         (buffer (find-file-noselect (expand-file-name "index.org" base-directory) t)))
    (with-current-buffer buffer
      (set-buffer-modified-p t)
      (save-buffer 0))
    (kill-buffer buffer)))

bba-ox-clip-formatted-copy

[2016-12-13 Tue 15:29]

(defun bba-ox-clip-formatted-copy()
  "wrapper for ox-clip-formatted-copy to disable org-export-use-babel."
  (interactive)
  (let ((org-export-use-babel nil))
    (ox-clip-formatted-copy (mark) (point)))
  )

(define-key org-mode-map "\M-\S-w" 'bba-ox-clip-formatted-copy)

bba-create-ticket-tmp-dir

[2017-07-28 Fri 13:07]

(defun bba-create-ticket-tmp-dir-open-dir-screen()
  "Create directory for the current ticket in tmp if not exist.
Open the directory of the current ticket in iterm screen via keyboard maestro."
  (interactive)
  (org-narrow-to-subtree)
  (let ((beg (point)))
    (goto-char (point-min))
    (if (re-search-forward "jira:" nil t 1)
        (if (org-in-regexp org-bracket-link-regexp 1)
            (let ((remove (list (match-beginning 0) (match-end 0)))
                  (description (last (split-string (if (match-end 3)
                                                       (match-string-no-properties 3)
                                                     (match-string-no-properties 1)) ":"))))
              (unless (file-exists-p (concat "~/tmp/" (downcase (car description))))
                                     (mkdir (concat "~/tmp/" (downcase (car description))))
                                     )
              (kill-new (concat "~/tmp/" (downcase (car description))))
              )))
    (goto-char beg)
    )
  (widen)
  (shell-command "osascript -e \'tell app \"Keyboard Maestro Engine\" to do script \"screen-start-cd-to-clipboard\"'")
  )

search notes

[2018-02-09 Fri 10:57]

Your notes are more useful if you can easily search them!

(defun snw ()
  "Search work notes."
  (interactive)
  (lgrep (read-string "search for regex:") "work*.org" "~/workorg"))

(defun sn ()
  "Search notes."
  (interactive)
  (lgrep (read-string "search for regex:") "notes.org" "~/org"))

Some initial languages we want org-babel to support

(org-babel-do-load-languages
 'org-babel-load-languages
 '(
   (shell . t)
   (python . t)
   (R . t)
   (ruby . t)
   (ditaa . t)
   (dot . t)
   (octave . t)
   (sqlite . t)
   (perl . t)
   (sql . t)
   ))

;;(setq org-html-preamble nil
;;     org-html-postamble nil
;;      org-html-head "")

;; (setq org-html-preamble nil
;;       org-html-postamble nil
;;       org-html-include-default-style nil
;;       org-html-head ""
;;       org-export-html-with-timestamp nil
;;       org-export-html-style "body-only"
;; )
;; body-only option ?

;; (setq html (org-export-as-html 3 nil nil 1))

open current directory in finder

[2017-01-09 Mon 15:18]

Sometimes you need a file finder in the current buffers directory.

 (defun bba-open-file-dir-finder ()
   "Open the directory of the current file in finder."
   (interactive)
   (if (string-equal system-type "darwin")
	(shell-command (concat "open " (file-name-directory (buffer-file-name))))
     )
   )

open current directory in iterm screen

[2017-02-14 Tue 12:24]

Open current buffers directory in gnu screen in iterm.

 (defun bba-open-file-dir-screen ()
   "Open the directory of the current file in iterm screen via keyboard maestro."
   (interactive)
   (if (string-equal system-type "darwin")
	(progn
	  (if (null buffer-file-name)
	      (kill-new default-directory)
	      (kill-new (file-name-directory (buffer-file-name))))
	  (shell-command "osascript -e \'tell app \"Keyboard Maestro Engine\" to do script \"screen-start-cd-to-clipboard\"'")
	  )
     )
   )


Find next and previous #+BEGIN_SRC sh block.

Very useful for repetitive literate devops jobs. <C-c> <S-n> then <C-c><C-c> and so on.

(add-hook 'org-mode-hook
          (lambda ()

            (fset 'bba/org-search-src-sh
                  (lambda (&optional arg) "Find next BEGIN_SRC sh block." (interactive "p") (kmacro-exec-ring-item (quote ([19 94 35 92 43 66 69 71 73 78 95 83 82 67 32 115 104 down] 0 "%d")) arg)))
            (define-key org-mode-map "\C-c\S-n" 'bba/org-search-src-sh)

            (fset 'bba/org-search-src-sh-reverse
                  (lambda (&optional arg) "Find previous BEGIN_SRC sh block." (interactive "p") (kmacro-exec-ring-item (quote ([18 94 35 92 43 66 69 71 73 78 95 83 82 67 32 115 104 18 down] 0 "%d")) arg)))
            (define-key org-mode-map "\C-c\S-p" 'bba/org-search-src-sh-reverse)
))

copy previous src block

[2016-08-25 Thu 23:36]

This is helpful in training sessions.

(defun bba-copy-and-yank-org-src-block()
  "copy last org src block and insert it at point.
If region is active copy only the src begin and src end lines."
  (interactive)
  (if (use-region-p)
      (progn
        (let (-p1 -p2 srclength)
          (setq -p1 (region-beginning) -p2 (region-end))
          (setq mark-active nil)
          (re-search-backward "\#\\+BEGIN_SRC")
      (forward-line -1)
      (if  (not (looking-at "\#"))(forward-line))
          (set-mark-command nil)
          (forward-line)
          (beginning-of-line)
          (kill-ring-save 1 1 1)
          (goto-char -p1)
          (set-mark-command nil)
          (insert (pop kill-ring))
          (setq srclength (- (region-end) (region-beginning)))
          (setq mark-active nil)
          (re-search-backward "\#\\+END_SRC")
          (set-mark-command nil)
          (forward-line)
          (beginning-of-line)
          (kill-ring-save 1 1 1)
          (kill-append "\n" nil)
          (goto-char (+ -p2 srclength))
          (insert (pop kill-ring))
          )
        )
    (progn
      (push-mark)
      (re-search-backward "\#\\+BEGIN_SRC")
  (forward-line -1)
  (if  (not (looking-at "\#"))(forward-line))
      (set-mark-command nil)
      (re-search-forward "\#\\+END_SRC")
      (forward-line)
      (beginning-of-line)
      (kill-ring-save 1 1 1)
      (set-mark-command '1)
      (set-mark-command '1)
      (insert (pop kill-ring))
      (re-search-backward "\#\\+BEGIN_SRC")
      (forward-line)
      ))
  )

(defun bba-copy-org-src-block()
  "copy last org src block. Can be around point, too."
  (interactive)
  (push-mark)
  (goto-char (point-at-bol))
  (if  (not (looking-at "\#\\+BEGIN_SRC"))(re-search-backward "\#\\+BEGIN_SRC"))
  (forward-line -1)
  (if  (not (looking-at "\#"))(forward-line))
  (set-mark-command nil)
  (re-search-forward "\#\\+END_SRC")
  (forward-line)
  (goto-char (point-at-bol))
  (kill-ring-save 1 1 1)
  (set-mark-command '1)
  (set-mark-command '1)
  )

(define-key org-mode-map "\C-c\S-w" 'bba-copy-and-yank-org-src-block)
(define-key org-mode-map (kbd "C-c s-w") 'bba-copy-org-src-block)

tmux capture-pane

[2016-10-08 Sat 13:43]

Recently I had to get screen-shots of a ncurses based tool. script, gnu screen and iterm2 were not very helpful because ncurses repositions the cursor and this information get’s lost in the log files created with them. tmux and ansifilter came to the rescue.

Of course I wanted the screen-shots in my orgmode files.

To make it short you can run a terminal window in standard 80x24 with tmux in it. start your tasks and every time you need a screen-shot run bba-org-tmux-capture-pane in your org notes file. You get a src sh code block with the screen-shot. Additionally save the below code snippet as tmuxhardcopy.sh. Then you have the ANSI color version sitting in your /tmp/ directory.

Of course you will loose the information of what was selected in your ncurses tool. But don’t worry: Select the start and end point in that line of your screen-shot and call bba-insert-arrows. Here is an example what you will have finally:

──────────────────────────────────────────────────────────────────────────────

        ┌──────────────────────────────────────────────────────────┐
        │ Main Menu                                                │
        │ ┌──────────────────────────────────────────────────────┐ │
        │ │        1  View Database Cluster State                │ │
        │ │  ->    2  Connect to Database                   <-   │ │
        │ │        3  Start Database                             │ │
        │ │        4  Stop Database                              │ │
        │ │        5  Restart Vertica on Host                    │ │
        │ │        6  Configuration Menu                         │ │
        │ │        7  Advanced Menu                              │ │
        │ │        8  Help Using the Administration Tools        │ │
        │ │        E  Exit                                       │ │
        │ └──────────────────────────────────────────────────────┘ │
        ├──────────────────────────────────────────────────────────┤
        │           <  OK  >      <Cancel>      < Help >           │
        └──────────────────────────────────────────────────────────┘

Here is the code:

(defun bba-org-tmux-capture-pane()
  "capture pane of tmux window and insert it as org-mode sh src block."
  (interactive)
  (insert "#+BEGIN_SRC sh")
  (newline)
  (insert (shell-command-to-string "tmux capture-pane -eJp | ansifilter"))
  (shell-command "tmuxhardcopy.sh")
  (insert "#+END_SRC")
  (newline)
  (forward-line -2)
  (org-edit-special)
  (delete-trailing-whitespace)
  (org-edit-src-exit)
  (forward-line 2)
  )

To capture the raw output from tmux including the ANSI colors and see selections I call this script:

#!/bin/sh
COUNTER=00
FILE=/tmp/tmux.hardcopy
/opt/local/bin/tmux capture-pane -eJ

for i in 0{1..9} {10..99}; do
    if ! [ -e ${FILE}${i} ]; then
        COUNTER=${i}
        break
    fi
done

/opt/local/bin/tmux save-buffer ${FILE}${COUNTER}

insert arrow

[2016-10-07 Fri 12:25]

I am using ansifilter to convert ncurses screenshots to ascii only. That way I can include them into org files as documentation. The downside of this process: I loose the selections. As a replacement you can use this function. Select the start and end points where you want to have ascii arrows and call this function.

(defun bba-insert-arrows()
  "insert ascii arrows at start and end of selection."
  (interactive)
  (insert "<-")
  (delete-char 2)
  (exchange-point-and-mark)
  (insert "->")
  (delete-char 2)
  (exchange-point-and-mark)
)

Define some shortcuts to access major org files.

(global-set-key (kbd "C-c <f5>") '(lambda () (interactive) (find-file "~/org/notes.org")))

(global-set-key (kbd "C-c <f7>") '(lambda () (interactive) (find-file "~/org/private.org")))
(global-set-key (kbd "C-c <f8>") '(lambda () (interactive) (find-file "~/org/workhours.org")))
(if (equal "work" (getenv "SYSENV"))
    (progn
      (global-set-key (kbd "C-c <f6>") '(lambda () (interactive) (find-file "~/workorg/work.org")))
      (global-set-key (kbd "C-c S-<f6>") '(lambda () (interactive) (find-file "~/workorg/work_archive.org")))
      (global-set-key (kbd "C-c C-<f6>") '(lambda () (interactive) (org-id-goto "0C6EAD45-9046-4A56-96C3-3B378A444263")))
      )
  (progn
    (global-set-key (kbd "C-c <f6>") '(lambda () (interactive) (find-file "~/org/work.org")))
    ))

(global-set-key (kbd "C-c <f9>") '(lambda () (interactive)
                                    ( if (file-exists-p "~/org/emacs.org")
                                        (find-file "~/org/emacs.org")
                                      (find-file "~/.emacs.d/org/emacs.org"))))
(global-set-key (kbd "C-c <f10>") '(lambda () (interactive) (find-file "~/.emacs.d/bba.org")))

Tag tasks with GTD contexts

(setq org-tag-alist '(("@work" . ?b)
                      ("@home" . ?h)
                      ("@errands" . ?e)
                      ("@coding" . ?c)
                      ("@phone" . ?p)
                      ("@reading" . ?r)
                      ("@computer" . ?l)
                      ))
;; (setq org-clock-persist 'history)
(org-clock-persistence-insinuate)
(setq org-clock-persist t)
(setq org-default-notes-file (concat org-directory "/refile.org"))
(define-key global-map "\C-cc" 'org-capture)

(setq org-capture-templates

'(("t" "todo" entry (file+headline "~/org/refile.org" "Tasks")
"* TODO %^{Task}\n%U\n

%i\n
%a\n
%?
")

  ("m" "Meeting" entry (file "~/org/refile.org")
   "* MEETING with %? :MEETING:\n%U" :clock-in t :clock-resume t)

  ("n" "note" entry (file+headline "~/org/refile.org" "Note")
   "* NOTE %?\n%U\n

%i\n
%a")

  ("w" "work todo" entry (file+headline "~/workorg/work.org" "Tasks")
"* TODO %^{Task}\n%U\n

%i\n
%a\n
%?
")

("j" "Journal" entry (file+datetree "~/git/org/diary.org")
 "* %?\n%U\n" :clock-in t :clock-resume t)

("l" "Links (it)" entry (file+headline "~/org/refile.org" "Links")
"** %c\n\n  %u\n  %i"
         :empty-lines 1)
("C" "Cookbook" entry (file+headline "~/org/kitchen.org" "[[http://allrecipes.com][AllRecipes.com]]")
 "%(org-chef-get-recipe-from-url)"
  :empty-lines 1)))

Define some handy link abbreviations

(setq org-link-abbrev-alist '(
("bing" . "http://www.bing.com/search?q=%sform=OSDSRC")
("cpan" . "http://search.cpan.org/search?query=%s&mode=all")
("google" . "http://www.google.com/search?q=")
("gmap" . "http://maps.google.com/maps?q=%s")
("omap" . "http://nominatim.openstreetmap.org/search?q=%s&polygon=1")
("bmap" . "http://www.bing.com/maps/default.aspx?q=%s&mkt=en&FORM=HDRSC4")
("wiki" . "http://en.wikipedia.org/wiki/")
("rfc" . "http://tools.ietf.org/rfc/rfc%s.txt")
("ads" . "http://adsabs.harvard.edu/cgi-bin/nph-abs_connect?author=%s&db_key=AST")
("vertica" . "https://my.vertica.com/docs/7.2.x/HTML/Content/Search/index.htm?q=%s")
))
;; example: [[bmap:space needle]]

Some clock stuff.

taken from http://doc.norang.ca/org-mode.org

  ;;
  ;; Resume clocking task when emacs is restarted
  (org-clock-persistence-insinuate)
  ;;
  ;; Show lot of clocking history so it's easy to pick items off the C-F11 list
  (setq org-clock-history-length 23)
  ;; Resume clocking task on clock-in if the clock is open
  (setq org-clock-in-resume t)
  ;; Change tasks to NEXT when clocking in
  (setq org-clock-in-switch-to-state 'bh/clock-in-to-next)
  ;; Separate drawers for clocking and logs
  (setq org-drawers (quote ("PROPERTIES" "LOGBOOK" "RESULTS")))
  ;; Save clock data and state changes and notes in the LOGBOOK drawer
  (setq org-clock-into-drawer t)
  ;; Sometimes I change tasks I'm clocking quickly - this removes clocked tasks with 0:00 duration
  (setq org-clock-out-remove-zero-time-clocks t)
  ;; Clock out when moving task to a done state
  (setq org-clock-out-when-done t)
  ;; Save the running clock and all clock history when exiting Emacs, load it on startup
  (setq org-clock-persist t)
  ;; Do not prompt to resume an active clock
  (setq org-clock-persist-query-resume nil)
  ;; Enable auto clock resolution for finding open clocks
  (setq org-clock-auto-clock-resolution (quote when-no-clock-is-running))
  ;; Include current clocking task in clock reports
  (setq org-clock-report-include-clocking-task t)
  (setq org-duration-format
        '(:hours "%d" :require-hours t :minutes ":%02d" :require-minutes t))
  (setq bh/keep-clock-running nil)

(defun bh/is-project-p ()
  "Any task with a todo keyword subtask"
  (save-restriction
    (widen)
    (let ((has-subtask)
          (subtree-end (save-excursion (org-end-of-subtree t)))
          (is-a-task (member (nth 2 (org-heading-components)) org-todo-keywords-1)))
      (save-excursion
        (forward-line 1)
        (while (and (not has-subtask)
                    (< (point) subtree-end)
                    (re-search-forward "^\*+ " subtree-end t))
          (when (member (org-get-todo-state) org-todo-keywords-1)
            (setq has-subtask t))))
      (and is-a-task has-subtask))))

  (defun bh/clock-in-to-next (kw)
    "Switch a task from TODO to NEXT when clocking in.
  Skips capture tasks, projects, and subprojects.
  Switch projects and subprojects from NEXT back to TODO"
    (when (not (and (boundp 'org-capture-mode) org-capture-mode))
      (cond
       ((and (member (org-get-todo-state) (list "TODO"))
             (bh/is-task-p))
        "NEXT")
       ((and (member (org-get-todo-state) (list "NEXT"))
             (bh/is-project-p))
        "TODO"))))

  (defun bh/find-project-task ()
    "Move point to the parent (project) task if any"
    (save-restriction
      (widen)
      (let ((parent-task (save-excursion (org-back-to-heading 'invisible-ok) (point))))
        (while (org-up-heading-safe)
          (when (member (nth 2 (org-heading-components)) org-todo-keywords-1)
            (setq parent-task (point))))
        (goto-char parent-task)
        parent-task)))

  (defun bh/punch-in (arg)
    "Start continuous clocking and set the default task to the
  selected task.  If no task is selected set the Organization task
  as the default task."
    (interactive "p")
    (setq bh/keep-clock-running t)
    (if (equal major-mode 'org-agenda-mode)
        ;;
        ;; We're in the agenda
        ;;
        (let* ((marker (org-get-at-bol 'org-hd-marker))
               (tags (org-with-point-at marker (org-get-tags-at))))
          (if (and (eq arg 4) tags)
              (org-agenda-clock-in '(16))
            (bh/clock-in-organization-task-as-default)))
      ;;
      ;; We are not in the agenda
      ;;
      (save-restriction
        (widen)
        ; Find the tags on the current task
        (if (and (equal major-mode 'org-mode) (not (org-before-first-heading-p)) (eq arg 4))
            (org-clock-in '(16))
          (bh/clock-in-organization-task-as-default)))))

  (defun bh/punch-out ()
    (interactive)
    (setq bh/keep-clock-running nil)
    (when (org-clock-is-active)
      (org-clock-out))
    (org-agenda-remove-restriction-lock))

  (defun bh/clock-in-default-task ()
    (save-excursion
      (org-with-point-at org-clock-default-task
        (org-clock-in))))

  (defun bh/clock-in-parent-task ()
    "Move point to the parent (project) task if any and clock in"
    (let ((parent-task))
      (save-excursion
        (save-restriction
          (widen)
          (while (and (not parent-task) (org-up-heading-safe))
            (when (member (nth 2 (org-heading-components)) org-todo-keywords-1)
              (setq parent-task (point))))
          (if parent-task
              (org-with-point-at parent-task
                (org-clock-in))
            (when bh/keep-clock-running
              (bh/clock-in-default-task)))))))

  ;; (defvar bh/organization-task-id "eb155a82-92b2-4f25-a3c6-0304591af2f9")
  (defvar bh/organization-task-id "20140625-424242-424242")

  (defun bh/clock-in-organization-task-as-default ()
    (interactive)
    (org-with-point-at (org-id-find bh/organization-task-id 'marker)
      (org-clock-in '(16))))

  (defun bh/clock-out-maybe ()
    (when (and bh/keep-clock-running
               (not org-clock-clocking-in)
               (marker-buffer org-clock-default-task)
               (not org-clock-resolving-clocks-due-to-idleness))
      (bh/clock-in-parent-task)))

  (add-hook 'org-clock-out-hook 'bh/clock-out-maybe 'append)

  (defvar bh/insert-inactive-timestamp t)

  (defun bh/toggle-insert-inactive-timestamp ()
    (interactive)
    (setq bh/insert-inactive-timestamp (not bh/insert-inactive-timestamp))
    (message "Heading timestamps are %s" (if bh/insert-inactive-timestamp "ON" "OFF")))

  (defun bh/insert-inactive-timestamp ()
    (interactive)
    (org-insert-time-stamp nil t t nil nil nil))

  (defun bh/insert-heading-inactive-timestamp ()
    (save-excursion
      (when bh/insert-inactive-timestamp
        (org-return)
        (org-cycle)
        (bh/insert-inactive-timestamp))))

  (add-hook 'org-insert-heading-hook 'bh/insert-heading-inactive-timestamp 'append)

  ; Targets include this file and any file contributing to the agenda - up to 9 levels deep
  (setq org-refile-targets (quote ((nil :maxlevel . 9)
                                   (org-agenda-files :maxlevel . 9))))

  ; Use full outline paths for refile targets - we file directly with IDO
  (setq org-refile-use-outline-path t)

  ; Targets complete directly with IDO
  (setq org-outline-path-complete-in-steps nil)

  ; Allow refile to create parent tasks with confirmation
  (setq org-refile-allow-creating-parent-nodes (quote confirm))

  ;; Use IDO for both buffer and file completion and ido-everywhere to t
  ;(setq org-completion-use-ido t)
  ;(setq ido-everywhere t)
  ;(setq ido-max-directory-size 100000)
  ;(ido-mode (quote both))
  ; Use the current window when visiting files and buffers with ido
  ;(setq ido-default-file-method 'selected-window)
  ;(setq ido-default-buffer-method 'selected-window)
  ; Use the current window for indirect buffer display
  (setq org-indirect-buffer-display 'current-window)

  ;;;; Refile settings
  ; Exclude DONE state tasks from refile targets
  (defun bh/verify-refile-target ()
    "Exclude todo keywords with a done state from refile targets"
    (not (member (nth 2 (org-heading-components)) org-done-keywords)))

  (setq org-refile-target-verify-function 'bh/verify-refile-target)


  (global-set-key (kbd "<f12>") 'org-agenda)
  (global-set-key (kbd "<f9> c") 'calendar)
  (global-set-key (kbd "<f9> I") 'bh/punch-in)
  (global-set-key (kbd "<f9> O") 'bh/punch-out)
  (global-set-key (kbd "<f9> t") 'bh/insert-inactive-timestamp)
  (global-set-key (kbd "<f9> T") 'bh/toggle-insert-inactive-timestamp)
  (global-set-key (kbd "C-<f9>") 'previous-buffer)
  (global-set-key (kbd "C-<f10>") 'next-buffer)
  (global-set-key (kbd "<f11>") 'org-clock-goto)
  (global-set-key (kbd "C-<f11>") 'org-clock-in)



(if (>= emacs-major-version 24)
    (progn
      (add-hook 'org-mode-hook
                (lambda ()
                  (auto-fill-mode)
                  (flyspell-mode -1)
                  (define-key org-mode-map "\C-h\C-y" '(lambda () (interactive) (find-file "~/.emacs.d/snippets/org-mode.org")))
                  (when (display-graphic-p)
                    (progn
                      (org-bullets-mode 1)
                      (rainbow-delimiters-mode))
                    )
                  )
                )
      (add-hook 'text-mode-hook
                (lambda ()
                  (auto-fill-mode)
                  (flyspell-mode)
                  )
                )
      (add-hook 'snippet-mode-hook
                (lambda ()
                  (auto-fill-mode -1)
                  (flyspell-mode -1)
                  )
                )
      (add-hook 'prog-mode-hook
                (lambda ()
                  (when (display-graphic-p)
                    (rainbow-delimiters-mode))
                  )
                )
      (add-hook 'eshell-mode-hook
                (lambda ()
                  (smartparens-mode t)
                  )
                )
      )
  (progn
    (add-hook 'org-mode-hook
              (lambda ()
                (auto-fill-mode)
                (define-key org-mode-map "\C-h\C-y" '(lambda () (interactive) (find-file "~/.emacs.d/snippets/org-mode.org"))))
              ))

  )

youtube links

Thanks to endlessparentheses: Youtube makes it pretty simple to embed videos, they give you the entire iframe HTML code to use, but this wouldn’t really be Emacs if we couldn’t make things just a little bit easier.

(defvar yt-iframe-format
  ;; You may want to change your width and height.
  (concat "<iframe width=\"440\""
          " height=\"335\""
          " src=\"https://www.youtube.com/embed/%s\""
          " frameborder=\"0\""
          " allowfullscreen>%s</iframe>"))

(org-add-link-type
 "yt"
 (lambda (handle)
   (browse-url
    (concat "https://www.youtube.com/embed/"
            handle)))
 (lambda (path desc backend)
   (cl-case backend
     (html (format yt-iframe-format
                   path (or desc "")))
     (latex (format "\href{%s}{%s}"
                    path (or desc "video"))))))

To use this, just write your org links in the following way (optionally adding a description).

yt:A3JAlWM8qRM

When you export to HTML, this will produce that same inlined snippet that Youtube specifies. The advantage (over simply writing out the iframe) is that this link can be clicked in org-mode, and can be exported to other formats as well.

org-mime-org-buffer-htmlize

Use C-c M to send a multipart email with .org as text and exported html.

(load-file "~/.emacs.d/elpa/org-mime-20181023.2314/org-mime.el")
(add-hook 'org-mode-hook
          (lambda()
            (define-key org-mode-map "\C-c\S-m" 'org-mime-org-buffer-htmlize)))

org-bullets

(load-file "~/.emacs.d/lisp/org-bullets.el")
(require 'org-bullets)
(add-hook 'org-mode-hook (lambda () (org-bullets-mode 1)))

org-ellipsis

(when (display-graphic-p)
  (setq org-ellipsis " ↴↴↴")
  )

fontify

(setq org-src-fontify-natively t)

hide emphasis-markers

(setq org-hide-emphasis-markers t)
(setq org-catch-invisible-edits 'smart)

underscore in export

[2016-10-28 Fri 12:08]

(setq org-export-with-sub-superscripts nil)

css style html export

[2016-10-28 Fri 12:21]

run toggle-org-custom-inline-style in a org buffer associated with a file.

;; put your css files there
(defvar org-theme-css-dir "~/.emacs.d/org-css/")
(defvar org-theme-css)

(defun toggle-org-custom-inline-style ()
  (interactive)
  (let ((hook 'org-export-before-parsing-hook)
        (fun 'set-org-html-style))
    (if (memq fun (eval hook))
        (progn
          (remove-hook hook fun 'buffer-local)
          (message "Removed %s from %s" (symbol-name fun) (symbol-name hook)))
      (add-hook hook fun nil 'buffer-local)
      (message "Added %s to %s" (symbol-name fun) (symbol-name hook)))))

(defun org-theme ()
  (interactive)
  (let* ((cssdir org-theme-css-dir)
         (css-choices (directory-files cssdir nil ".css$"))
         (css (completing-read "theme: " css-choices nil t)))
    (concat cssdir css)))

(defun set-org-html-style (&optional backend)
  (interactive)
  (when (or (null backend) (eq backend 'html))
    (let ((f (or (and (boundp 'org-theme-css) org-theme-css) (org-theme))))
      (if (file-exists-p f)
          (progn
            (set (make-local-variable 'org-theme-css) f)
            (set (make-local-variable 'org-html-head)
                 (with-temp-buffer
                   (insert "<style type=\"text/css\">\n<!--/*--><![CDATA[/*><!--*/\n")
                   (insert-file-contents f)
                   (goto-char (point-max))
                   (insert "\n/*]]>*/-->\n</style>\n")
                   (buffer-string)))
            (set (make-local-variable 'org-html-head-include-default-style)
                 nil)
            (message "Set custom style from %s" f))
        (message "Custom header file %s doesnt exist" f)))))

org-sticky-header

[2017-04-26 Wed 13:09]

(add-to-list 'load-path "~/.emacs.d/elpa/org-sticky-header-20170423.435" t)
(add-hook 'org-mode-hook
	      (lambda ()(org-sticky-header-mode 1))
	    )

additional org settings

[2016-11-03 Thu 09:36] Thanks to eos-org.

Special begin/end of line to skip tags and stars

(setq org-special-ctrl-a/e t)

Special keys for killing a headline

(setq org-special-ctrl-k t)

blank lines are removed when exiting the code edit buffer

(setq org-src-strip-leading-and-trailing-blank-lines t)

Return on a link breaks the link? Just follow it.

(setq org-return-follows-link t)

Smart yanking: https://www.gnu.org/software/emacs/manual/html_node/org/Structure-editing.html

(setq org-yank-adjusted-subtree t)
(setq org-tags-column -102)

use emacs as default. Otherwise executables without extension get executed instead of opened.

(setq org-file-apps '((auto-mode . emacs)
			("\\.mm\\'" . default)
			("\\.x?html?\\'" . default)
			("\\.pdf\\'" . default)
			( t . emacs)))

goto-address-mode

[2018-08-28 Tue 20:34]

(eval-after-load "prog-mode"
  '(progn
     (add-hook 'prog-mode-hook 'goto-address-prog-mode)
     (define-key prog-mode-map "\C-c\C-o" 'goto-address-at-point)))
(eval-after-load "eshell-mode"
  '(progn
     (add-hook 'eshell-mode 'goto-address-mode)
     (define-key eshell-mode-map "\C-c\C-o" 'goto-address-at-point)))
(eval-after-load "shell-mode"
  '(progn
     (add-hook 'shell-mode 'goto-address-mode)
     (define-key shell-mode-map "\C-c\C-o" 'goto-address-at-point)))

CFEngine

;;   (load-library "cfengine")
   (load-file (expand-file-name "~/.emacs.d/lisp/cfengine.el"))
   (add-to-list 'auto-mode-alist '("\\.cf$" . cfengine3-mode))

   ;; post-commit and post-merge hook for git:
   ;; #!/bin/bash
   ;; rm .git/etags
   ;; find ${PWD} -type f -regex ".*\(\.cf\|_pl\.dat\|_conf.dat\)" | xargs etags --append --output=.git/etags
   ;; set link for emacs:
   ;; ln -s ~/.cfagent/inputs/../.git/etags ~/.cfengine_tags

   (defun load-git-cfengine ()
     "Load config and tags file of git cfengine repo"
   (interactive) (visit-tags-table "~/.cfengine_tags")
   (find-file "~/.cfagent/inputs/config.cf")
   )

   ;; cfe-config-adduser-ldap runs ldapsearch with cn=user to fill some values.

   (defun cfe-config-adduser-ldap ( user )
     "Insert usertemplate based on ldap information for config.cf"
     (interactive "sUser: ")
     (insert "      \"users[" user "][login]\" string => \"" user "\";
         \"users[" user "][fullname]\" string => \"" (substring ( shell-command-to-string (concat "ldapse " user " givenName ")) 0 -1) " " (substring ( shell-command-to-string (concat "ldapse " user " sn ")) 0 -1) "\";
         \"users[" user "][uid]\" string => \"" (substring ( shell-command-to-string (concat "ldapse " user " uidNumber")) 0 -1) "\";
         \"users[" user "][gid]\" string => \"" (substring ( shell-command-to-string (concat "ldapse " user " uidNumber")) 0 -1)"\";
         \"users[" user "][group]\" string => \"" user "\";
         \"users[" user "][groups]\" string => \"adm,apache,games\";
         \"users[" user "][home]\" string => \"/home/" user "\";
         \"users[" user "][shell]\" string => \"/bin/bash\";
         \"users[" user "][flags]\" string => \"-m\";
         \"users[" user "][authorized_keys][0]\" string => \"\";" )

   )

   (defun cfe-config-adduser ( user )
     "Insert usertemplate for config.cf"
     (interactive "sUser: ")
     (insert "      \"users[" user "][login]\" string => \"" user "\";
         \"users[" user "][fullname]\" string => \"\";
         \"users[" user "][uid]\" string => \"\";
         \"users[" user "][gid]\" string => \"\";
         \"users[" user "][group]\" string => \"" user "\";
         \"users[" user "][groups]\" string => \"" user "\";
         \"users[" user "][home]\" string => \"/home/" user "\";
         \"users[" user "][shell]\" string => \"/bin/bash\";
         \"users[" user "][flags]\" string => \"-m\";
         \"users[" user "][authorized_keys][0]\" string => \"\";" )

   )

   (add-hook 'cfengine3-mode-hook
     (lambda ()
       (which-function-mode)

       (define-key cfengine3-mode-map "\C-c\S-t" (lambda()
                                                   (interactive)
                                                   (shell-command "~/bin/cfengine_update_testing.sh" )))
       (define-key cfengine3-mode-map "\C-cu" 'cfe-config-adduser-ldap)
       (define-key cfengine3-mode-map "\C-c\C-c" 'compile)
       (define-key cfengine3-mode-map "\C-c," (lambda()
                                                 (interactive)
                                                 (browse-url (concat "https://docs.cfengine.com/latest/search.html?q=" (word-at-point)))))
         (define-key cfengine3-mode-map "\C-h\C-y" '(lambda () (interactive) (find-file "~/.emacs.d/snippets/cfengine3-mode.org")))
       ))

for C-c T you can use a file like this one:

#!/bin/bash
:<<cut
=cut

=pod

=head1 NAME

cfengine_update_testing

=head1 DESCRIPTION

sync cfengine inputs to agtest03 and run failsafe.

=cut

cf-promises -D customlib_active || exit 3
rsync -av --progress --delete -e ssh ~/.cfagent/inputs/ agtest03:/var/cfengine/masterfiles/
ssh agtest03 "/usr/local/sbin/cf-agent -f /var/cfengine/inputs/failsafe.cf"

:<<=cut

=head1 AUTHOR

Andreas Gerler <baron@bundesbrandschatzamt.de>

=cut

Puppet

[2016-02-29 Mon 16:36]

(add-to-list 'auto-mode-alist '("\\.erb$" . rhtml-mode))

Ruby

[2016-03-11 Fri 12:18]

Vagrant files are Ruby, so use ruby-mode for them:

(add-to-list 'auto-mode-alist '("Vagrantfile" . ruby-mode))
(defun bba-ruby-lint()
(interactive)
"check current buffer via ruby"
(let* ((buffer-file-name (or (buffer-file-name) ""))
         (filename (or (file-remote-p buffer-file-name 'localname)
			 buffer-file-name))
	   (command (concat "ruby -c "
				 (shell-quote-argument filename)))
	   )
    (compilation-start (concat "ruby -c "
				 (shell-quote-argument filename))
			 nil
			 (lambda (_) (format "*Ruby Validate: %s*" command))
			 ))
)

mwheel

(load-library "mwheel")
(mwheel-install)

tip of the day

[2014-09-24 Wed 12:06]

Display an Emacs tip of the day. You may start it at the end of the config file.

(defun totd ()
  (interactive)
  (random t) ;; seed with time-of-day
  (with-output-to-temp-buffer "*Tip of the day*"
    (let* ((commands (loop for s being the symbols
                           when (commandp s) collect s))
           (command (nth (random (length commands)) commands)))
      (princ
       (concat "Your tip for the day is:\n"
               "========================\n\n"
               (describe-function command)
               "\n\nInvoke with:\n\n"
               (with-temp-buffer
                 (where-is command t)
                 (buffer-string)))))))

TRAMP

(load-library "tramp")
(add-to-list 'tramp-remote-path "~/bin")
(setq default-tramp-method "sshx")

With this you can do /sudo:ssh-host:file-on-ssh-host

(add-to-list 'tramp-default-proxies-alist '(nil "\\`root\\'" "/ssh:%h:"))

Use our default socket files

(if (file-accessible-directory-p "~/.ssh/sockets")
(setq tramp-ssh-controlmaster-options "-o ControlMaster=auto -o ControlPath=~/.ssh/sockets/ssh.%%C -o ControlPersist=600"))

twitter

(add-to-list 'load-path "~/.emacs.d/elpa/twittering-mode-20181121.1402")
(require 'twittering-mode)
(cond
 ((string-equal system-type "gnu/linux")
  (progn
    (setq twittering-cert-file "/etc/ssl/certs/ca-bundle.crt") )
  )
)

(setq twittering-use-master-password t)

(if (getenv "http_proxy")
    (twittering-toggle-proxy))

mew email

(autoload 'mew "mew" nil t)
(autoload 'mew-send "mew" nil t)

;; Optional setup (Red Mail menu):
(setq read-mail-command 'mew)

;; Optional setup (e.g. C-xm for sending a message):
(autoload 'new-user-agent-compose "mew" nil t)

(if (boundp 'mail-user-agent)
    (setq mail-user-agent 'mew-user-agent))
(if (fboundp 'define-mail-user-agent)
    (define-mail-user-agent
      'mew-user-agent
      'mew-user-agent-compose
      'mew-draft-send-message
      'mew-draft-kill
      'mew-send-hook))

When booting, Mew reads the file ~/.mew.el. All Mew configurations should be written in this file.

To configure your e-mail address, the followings are necessary.

;; (setq mew-name "your name") ;; (user-full-name)
;; (setq mew-user "user name of e-mail address") ;; (user-login-name)
(setq mew-mail-domain "domain of e-mail address")

To send e-mail messages by SMTP, the following is necessary.

(setq mew-smtp-server "your SMTP server") ;; if not localhost
;; (setq mew-smtp-ssl t)
;; (setq mew-smtp-port "587")

Here is an example for sending e-mail via gmail:

(setq
send-mail-function 'smtpmail-send-it
message-send-mail-function 'smtpmail-send-it
user-mail-address "foo@gmail.com"
smtpmail-starttls-credentials '(("smtp.gmail.com" "587" nil nil))
smtpmail-auth-credentials (expand-file-name "~/.authinfo.gpg")
smtpmail-default-smtp-server "smtp.gmail.com"
smtpmail-smtp-server "smtp.gmail.com"
smtpmail-smtp-service 587
smtpmail-debug-info t
starttls-extra-arguments nil
starttls-gnutls-program "/opt/local/bin/gnutls-cli"
starttls-extra-arguments nil
starttls-use-gnutls t
)
(load-library "smtpmail")

If you want to use POP to receive e-mail messages, the followings are necessary.

;; (setq mew-pop-user "your POP account") ;; (user-login-name)
(setq mew-pop-server "your POP server") ;; if not localhost

If you want to use a local mailbox to receive e-mail messages, the followings are necessary.

;; To use local mailbox "mbox" or "maildir" instead of POP
(setq mew-mailbox-type 'mew)
(setq new-mbox-command "incm")
(setq mew-mbox-command-arg "-u -d /path/to/mbox")
;; If /path/to/mbox is a file, it means "mbox".
;; If /path/to/mbox is a directory, it means "maildir".

If you want to use IMAP to receive e-mail-messages, the followings are necessary.

(setq mew-proto "%")
;; (setq mew-imap-user "your IMAP account) ;; (user-login-name)
(setq mew-imap-server "your IMAP server") ;; if not localhost
;; (setq mew-imap-ssl t)
;; (setq mew-imap-port "993)
;; (setq mew-prog-ssl-arg "fips=no\nverify=0\n")

To read and/or write articles of NetNews, the followings are necessary.

;; (setq mew-nntp-user "your NNTP account")
(setq mew-nntp-server "your NNTP server")

elfeed

(if (>= emacs-major-version 24)
    (progn
      (add-to-list 'load-path "~/.emacs.d/elpa/elfeed-20181127.1943")
      (add-to-list 'load-path "~/.emacs.d/elpa/elfeed-org-20181015.1100")
      (require 'elfeed-org)
      (elfeed-org)
      (setq rmh-elfeed-org-files (list "~/org/elfeed.org"))))

Mylon

(require 'malyon)

TemplateToolkit

(add-to-list 'auto-mode-alist '("\\.tt2$" . html-mode))

EPG/GPG

;; Do not use gpg agent when runing in terminal
(if (>= emacs-major-version 25)
(defadvice epg--start (around advice-epg-disable-agent activate)
  (let ((agent (getenv "GPG_AGENT_INFO")))
    (when (not (display-graphic-p))
      (setenv "GPG_AGENT_INFO" nil))
    ad-do-it
    (when (not (display-graphic-p))
      (setenv "GPG_AGENT_INFO" agent)))))

;; (defadvice epg--start (around advice-epg-disable-agent disable)
;;   "Don't allow epg--start to use gpg-agent in plain text terminals."
;;   (if (display-graphic-p)
;;       ad-do-it
;;     (let ((agent (getenv "GPG_AGENT_INFO")))
;;       (setenv "GPG_AGENT_INFO" nil) ; give us a usable text password prompt
;;       ad-do-it
;;       (setenv "GPG_AGENT_INFO" agent))))
;; (ad-enable-advice 'epg--start 'around 'advice-epg-disable-agent)
;; (ad-activate 'epg--start)

list who can decrypt a file:

(defun bba-epa-list-packets ()
  "List who can decrypt the current file"
  (interactive)
  (let ((bba-epa-filename (buffer-file-name))
    (bba-epa-packets-buffer (generate-new-buffer "*Packets*")))
    (set-buffer bba-epa-packets-buffer)
    (insert (shell-command-to-string (concat "gpg --list-packets " bba-epa-filename))
    ;; (epg--start context "--list-packets ")
    )
 ))
(defun bba-epa-list-packets ()
  "List who can decrypt the current file"
  (interactive)
  (require 'epa)
  (require 'epg)
  (let ((bba-epa-filename (buffer-file-name))
	  (bba-epa-packets-buffer (generate-new-buffer "*Packets*"))
	  (context (epg-make-context epa-protocol))
	  (epg-context-output-file context)
    )
    (set-buffer bba-epa-packets-buffer)
    ;; (setf (epg-context-output-file context))
    (epg--start context (list "--list-packets" bba-epa-filename))
    (epg-wait-for-completion context)
    (epg-read-output context)
 ))

Perl

(require 'cperl-mode)
(fset 'perl-mode 'cperl-mode)

(eval-after-load "cperl-mode"
  '(add-hook 'cperl-mode-hook (lambda() (cperl-set-style "GNU"))))

auto-completion

(add-to-list 'load-path "~/.emacs.d/elpa/auto-complete-20170125.245")
(require 'auto-complete-config)
(add-to-list 'ac-dictionary-directories "~/.emacs.d/elpa/auto-complete-20170125.245")
(add-to-list 'ac-dictionary-directories "~/.emacs.d/ac-dict")
(ac-config-default)
(add-to-list 'ac-modes 'cfengine3-mode)
(add-to-list 'ac-modes 'dns-mode)
(add-to-list 'ac-sources 'ac-source-yasnippet)

abbreviation

Watching Emacs For Writers by Jay Dixit I had to configure abbreviations.

(setq abbrev-file-name "~/org/abbrev_defs")
(if (file-exists-p abbrev-file-name)
    (quietly-read-abbrev-file))
(set-default 'abbrev-mode t)
(abbrev-mode )
(setq save-abbrevs 'silently)

Combine abbrev with Ispell:

Ispell and Abbrev, the Perfect Auto-Correct

(global-set-key (kbd "M-$") #'endless/ispell-word-then-abbrev)

(defun endless/simple-get-word ()
  (car-safe (save-excursion (ispell-get-word nil))))

(defun endless/ispell-word-then-abbrev (p)
  "Call `ispell-word', then create an abbrev for it.
With prefix P, create local abbrev. Otherwise it will
be global.
If there's nothing wrong with the word at point, keep
looking for a typo until the beginning of buffer. You can
skip typos you don't want to fix with `SPC', and you can
abort completely with `C-g'."
  (interactive "P")
  (let (bef aft)
    (save-excursion
      (while (if (setq bef (endless/simple-get-word))
                 ;; Word was corrected or used quit.
                 (if (ispell-word nil 'quiet)
                     nil ; End the loop.
                   ;; Also end if we reach `bob'.
                   (not (bobp)))
               ;; If there's no word at point, keep looking
               ;; until `bob'.
               (not (bobp)))
        (backward-word)
        (backward-char))
      (setq aft (endless/simple-get-word)))
    (if (and aft bef (not (equal aft bef)))
        (let ((aft (downcase aft))
              (bef (downcase bef)))
          (define-abbrev
            (if p local-abbrev-table global-abbrev-table)
            bef aft)
          (message "\"%s\" now expands to \"%s\" %sally"
                   bef aft (if p "loc" "glob")))
      (user-error "No typo at or before point"))))

stripes

[2017-07-11 Tue 15:17]

(load-file (expand-file-name "~/.emacs.d/lisp/stripes.el"))
(custom-set-faces
 '(stripes-face ((t :background "gray0"))))

syntax-highlighting

(font-lock-mode)
(global-font-lock-mode 1)

sql

[2016-11-27 Sun 17:56]

thanks to https://truongtx.me/2014/08/23/setup-emacs-as-an-sql-database-client

have a look in sql.el and extract the sql-product and set it before starting sql-connect.

(defun my-sql-connect ()
  (interactive)
  (require 'my-password "~/.emacs_secrets.el.gpg")
  (setq sql-product 'vertica)
  (let ((connection (helm-comp-read
                     "Select server: "
                     my-sql-servers-alist
                     )))
    (sql-connect connection))
  (sql-rename-buffer)
  )

your ~/.emacs_secrets.el.gpg might look like:

(setq my-sql-servers-alist
      '("bbaprd" "bbatst"))

(setq sql-connection-alist
      '((bbaprd (sql-product 'vertica)
                (sql-server "host42.foo.com")
                (sql-user "dbadmin")
                (sql-password "foo")
                (sql-database "smaatoprd"))
        (bbatst (sql-product 'vertica)
                (sql-server "host42.foo.com")
                (sql-user "dbadmin")
                (sql-password "foo")
                (sql-database "bbatst"))
        ))

(provide 'my-password)

sqlformat

[2016-08-19 Fri 16:20]

Provides the sqlformat command, which uses the external Python tool sqlformat to format SQL in the current buffer.

Be aware that if the buffer is mixed code/SQL then you need to select the SQL so that sqlformat only operates on the region, otherwise it acts on the whole buffer.

On OS X you might want to run sudo port install sqlparse to have sqlformat available.

(load-file (expand-file-name "~/.emacs.d/lisp/sqlformat.el"))
(add-hook 'sql-mode-hook
          (lambda ()
            (key-chord-define sql-mode-map "FF" 'sqlformat)))

sqlup

[2016-11-24 Thu 13:31]

Takes care of doing upper-case for keywords.

(add-to-list 'load-path "~/.emacs.d/elpa/sqlup-mode-20170610.1537")
(require 'sqlup-mode)
(add-hook 'sql-mode-hook 'sqlup-mode)
(add-hook 'sql-interactive-mode-hook 'sqlup-mode)

remove trailing whitespace

[2014-09-24 Wed 16:56]

There are some file formats out there where you shouldn’t use this function. YAML is only one of them. You can disable this functionality on a per file basis by adding lines like these:

# Local Variables:
# bba-keep-whitespaces: 1
# End:
(eval-after-load "cfengine3-mode"
  '(add-hook 'cfengine3-mode-hook (lambda() (add-hook 'write-contents-functions
                                                 (lambda()
                                                    (unless (boundp 'bba-keep-whitespaces)
                                                      (save-excursion
                                                        (delete-trailing-whitespace)))
                                                    )
                                                 )
                               )
             ))


(eval-after-load "cperl-mode"
  '(add-hook 'cperl-mode-hook (lambda() (add-hook 'write-contents-functions
                                                  (lambda()
                                                    (unless (boundp 'bba-keep-whitespaces)
                                                      (save-excursion
                                                        (delete-trailing-whitespace))))))))

(eval-after-load "dns-mode"
  '(add-hook 'dns-mode-hook (lambda() (add-hook 'write-contents-functions
                                                (lambda()
                                                  (save-excursion
                                                    (delete-trailing-whitespace)))))))

(eval-after-load "js-mode"
  '(add-hook 'js-mode-hook (lambda() (add-hook 'write-contents-functions
                                                 (lambda()
                                                   (save-excursion
                                                     (delete-trailing-whitespace)))))))

(eval-after-load "json-mode"
  '(add-hook 'json-mode-hook (lambda() (add-hook 'write-contents-functions
                                                 (lambda()
                                                   (unless (boundp 'bba-keep-whitespaces)
                                                    (save-excursion
                                                      (delete-trailing-whitespace))))))))

(eval-after-load "org-mode"
  '(add-hook 'org-mode-hook (lambda() (add-hook 'write-contents-functions
                                                (lambda()
                                                  (unless (boundp 'bba-keep-whitespaces)
                                                    (save-excursion
                                                      (delete-trailing-whitespace))))))))
(eval-after-load "puppet-mode"
  '(add-hook 'puppet-mode-hook (lambda() (add-hook 'write-contents-functions
                                                 (lambda()
                                                    (unless (boundp 'bba-keep-whitespaces)
                                                      (save-excursion
                                                        (delete-trailing-whitespace))))))))

(eval-after-load "text-mode"
  '(add-hook 'text-mode-hook (lambda() (add-hook 'write-contents-functions
                                                 (lambda()
                                                   (unless (boundp 'bba-keep-whitespaces)
                                                     (save-excursion
                                                       (delete-trailing-whitespace))))))))


rpm spec buildrpm

[2015-07-23 Thu 13:22]

Use C-c C-c to run rpmbuild if buffer is spec file.

(defun bba-build-rpm ()
"Do rpmbuild -ba, with the current buffers filename."
(interactive)
(string-match "\\([^:]*\\)$" buffer-file-name)
(let* ((spec-file (match-string 1 buffer-file-name))
       )
  (compile (concat "rpmbuild -ba " spec-file))
  ;; (shell-command (concat "rpmbuild -ba " spec-file))
  )
)

(add-hook 'sh-mode-hook
          (lambda ()
            (progn
              (if (buffer-file-name)
                  (if (string-match ".spec$" buffer-file-name)
                      (define-key sh-mode-map "\C-c\C-c" 'bba-build-rpm)))
    )))

undo tree

Use undo-tree.

(if (>= emacs-major-version 24)
    (global-undo-tree-mode))

mode-line menu-bar etc

 (column-number-mode t)
 (line-number-mode t)
 (setq display-time-24hr-format t)
 (display-time)

 ( if (not window-system)
     (menu-bar-mode -1)
   )

 (if window-system
     (progn
	(tool-bar-mode -1)
	(scroll-bar-mode -1)
	)
 )

 (setq initial-scratch-message "") ;; Uh, I know what Scratch is for

Art Bollocks Mode

[2014-09-28 Sun 22:33]

Keeps track of your writing. Includes Flesch Reading Ease and Flesch Grade Level. With modifications by Sacha Chua.

(if (>= emacs-major-version 25)
    (progn
      (require 'artbollocks-mode)
      ;; Avoid these phrases
      (setq weasel-words-regex
            (concat "\\b" (regexp-opt
                           '("one of the"
                             "should"
                             "just"
                             "sort of"
                             "a lot"
                             "probably"
                             "maybe"
                             "perhaps"
                             "I think"
                             "really"
                             "pretty"
                             "maybe"
                             "nice"
                             "action"
                             "utilize"
                             "leverage") t) "\\b"))
      ;; Fix a bug in the regular expression to catch repeated words
      (setq lexical-illusions-regex "\\b\\(\\w+\\)\\W+\\(\\1\\)\\b")
      ;; Don't show the art critic words, or at least until I figure
      ;; out my own jargon
      (setq artbollocks nil)
      ;; Make sure keywords are case-insensitive
      (defadvice search-for-keyword (around sacha activate)
        "Match in a case-insensitive way."
        (let ((case-fold-search t))
          ad-do-it))

      (add-hook 'text-mode-hook 'artbollocks-mode)
      (add-hook 'org-mode-hook  'artbollocks-mode)
      )
  )

window management

[2014-09-24 Wed 13:03]

Bind f3 and f4 to previous/next pane. Bind shift f3 and shift f4 to previous/next frame.

(defun move-cursor-next-pane ()
  "Move cursor to the next pane."
  (interactive)
  (other-window 1))

(defun move-cursor-previous-pane ()
  "Move cursor to the previous pane."
  (interactive)
  (other-window -1))

(defun move-cursor-next-frame ()
  "Move cursor to the next frame."
  (interactive)
  (other-frame 1))

(defun move-cursor-previous-frame ()
  "Move cursor to the previous frame."
  (interactive)
  (other-frame -1))

(global-set-key (kbd "<f3>") 'move-cursor-previous-pane)
(global-set-key (kbd "S-<f3>") 'move-cursor-previous-frame)
(global-set-key (kbd "<f4>") 'move-cursor-next-pane)
(global-set-key (kbd "S-<f4>") 'move-cursor-next-frame)

Right from gisthub:

(defun twist-split ()
  (interactive)
  (setq buffer2 (window-buffer (second (window-list))))
  (if (window-top-child (frame-root-window))
  (progn (delete-other-windows) (split-window-horizontally))
  (progn (delete-other-windows) (split-window-vertically)))
  (set-window-buffer (second (window-list)) buffer2))

ipcalc

(require 'ipcalc)

RecentFiles

(require 'recentf)
(recentf-mode 1)
(setq recentf-max-saved-items 200
      recentf-max-menu-items 142)
(if (<= emacs-major-version 23)
    (global-set-key "\C-cr" 'recentf-open-files))

insert-date function

(defun bba-insert-date ()
"Insert the current date"
(interactive)
(insert (format-time-string "%B %e, %Y")))

(defun bba-insert-timestamp ()
"Insert the current timestamp"
(interactive)
(insert (format-time-string "%Y%m%d-%H%M")))

(defun bba-insert-name-timestamp ()
"Insert the current timestamp"
(interactive)
(insert (format-time-string "%a %b %e %Y") " " (or (and (boundp 'user-full-name) user-full-name) (user-full-name))" <" (getenv "EMAIL") ">" ))

(defun bba-insert-name ()
"Insert name and emailaddress of current systemuser."
(interactive)
(insert (or (and (boundp 'user-full-name) user-full-name) (user-full-name))" <" (getenv "EMAIL") ">" ))
(define-key global-map (kbd "s-n") 'bba-insert-name)

(defun bba-insert-changelog-signature ()
  "Insert name and timestamp in changelog format."
  (interactive)
  (insert " -- " (or (and (boundp 'user-full-name) user-full-name) (user-full-name))" <" (getenv "EMAIL") ">  " (format-time-string "%a, %d %b %Y %H:%M:%S %z")))

toggle fullscreen mode

[2016-06-22 Wed 14:23]

toggle full screen with super return. display battery status in fullscreen mode. disable scroll bar in fullscreen mode.

(defun bba-toggle-fullscreen()
  "toggle fullscreen mode"
  (interactive)
  (if (equal 'fullboth (frame-parameter nil 'fullscreen))
      (progn (set-frame-parameter nil 'fullscreen 'maximized)
             (display-battery-mode -1)
             (display-time-mode -1)
             (scroll-bar-mode -1)
             )
    (progn (set-frame-parameter nil 'fullscreen 'fullboth)
           (display-battery-mode 1)
           (display-time-mode 1)
           (scroll-bar-mode -1)
           )
      )
  )
(global-set-key (kbd "s-<return>") 'bba-toggle-fullscreen)

generate passwords

[2017-05-31 Wed 16:33]

(defun bba-insert-pw(v2)
"insert password"
(interactive "P")
(if v2
    (insert (shell-command-to-string "password2.pl"))
  (insert (shell-command-to-string "password.pl"))
  )
)
(define-key global-map (kbd "s-p") 'bba-insert-pw)

eshell-here

Thanks to Howard Abrams. modified because current version lacks function have window-total-height.

Bound to C-X l !

(defun eshell-here ()
  "Opens up a new shell in the directory associated with the
current buffer's file. The eshell is renamed to match that
directory to make multiple eshell windows easier."
  (interactive)
  (let* ((parent (if (buffer-file-name)
                     (file-name-directory (buffer-file-name))
                   default-directory))
     ;;    (height (/ (window-total-height) 3))
         (name   (car (last (split-string parent "/" t)))))
;;    (split-window-vertically (- height))
    (split-window-vertically '-10)
    (other-window 1)
    (eshell "new")
    (rename-buffer (concat "*eshell: " name "*"))

    (insert (concat "ls"))
    (eshell-send-input)))

(defun eshell/x ()
  (insert "exit")
  (eshell-send-input)
  (delete-window))



(defun eshell/ssh (&rest args)
"Secure shell"
(let ((cmd (eshell-flatten-and-stringify
(cons "ssh" args)))
(display-type (framep (selected-frame))))
(cond
((and
(eq display-type 't)
(getenv "STY"))
(send-string-to-terminal (format "\033]83;screen %s\007" cmd)))
((eq display-type 'x)
(eshell-do-eval
(eshell-parse-command
(format "rxvt -e %s &" cmd)))
nil)
(t
(apply 'eshell-exec-visual (cons "ssh" args))))))


(defun eshell-client (&optional arg)
  "Opens up a new shell in the directory passed as argument.
The eshell is renamed to match that directory to make multiple
eshell windows easier."
  (interactive)
  (let* ((name (if arg
                     arg
                   default-directory))
     ;;    (height (/ (window-total-height) 3))
         )
    (eshell "new")
    (rename-buffer (concat "*eshell: " name "*"))

    (insert (concat "ls"))
    (eshell-send-input)))

eval emacs lisp expression and replace it

[2014-11-02 Sun 18:21]

Use C-c E to evaluate and replace the last s-expression.

(defun bba/eval-last-sexp-replace ()
  "replace the last s-expression with its evaluated result"
  (interactive)
  (backward-kill-sexp)
  (prin1 (eval (read (current-kill 0)))
         (current-buffer)))

(define-key global-map "\C-c\S-e" 'bba/eval-last-sexp-replace)

goto-match-paren

(defun goto-match-paren (arg)
  "Go to the matching parenthesis if on parenthesis, otherwise insert %.
vi style of % jumping to matching brace."
  (interactive "p")
  (cond ((looking-at "\\s\(") (forward-list 1) (backward-char 1))
        ((looking-at "\\s\)") (forward-char 1) (backward-list 1))
        (t (self-insert-command (or arg 1)))))
(global-set-key "%" 'goto-match-paren)

safe hash bang files executable

safe files with #! in first line as user executable.

(add-hook `after-save-hook
          #'(lambda ()
              (if (not
                   (or
                    (string-match ".htm" buffer-file-name)
                    (string-match ".org" buffer-file-name))
                   )
                  (check-parens))

              (and (save-excursion
                     (save-restriction
                       (widen)
                       (goto-char (point-min))
                       (save-match-data
                         (looking-at "^#!"))))
                   (if (file-remote-p buffer-file-name)
                       (progn
                         (not (file-executable-p buffer-file-name))
                         (shell-command (concat "chmod u+x " (file-name-nondirectory buffer-file-name)))
                         (message
                          (concat "Saved as script via tramp: " buffer-file-name))
                         )
                     (progn
                       (not (file-executable-p buffer-file-name))
                       (shell-command (concat "chmod u+x " buffer-file-name))
                       (message
                        (concat "Saved as script: " buffer-file-name)))))))

fill-or-unfill paragraph

[2017-06-09 Fri 12:25]

(defun bba-fill-or-unfill ()
  "Like `fill-paragraph', but unfill if used twice."
  (interactive)
  (let ((fill-column
         (if (eq last-command 'bba-fill-or-unfill)
             (progn (setq this-command nil)
                    (point-max))
           fill-column)))
    (call-interactively 'fill-paragraph)))

(global-set-key [remap fill-paragraph]
                'bba-fill-or-unfill)

Move Cursor to Beginning of Line/Paragraph

[2017-03-02 Thu 13:46]

Thanks to Xah Lee:

 (defun xah-beginning-of-line-or-block ()
   "Move cursor to beginning of line, or beginning of current or previous text block.

 • When called first time, move cursor to beginning of line.
 • When called again, move cursor to beginning of paragraph.
 • When called again, move cursor to beginning of previous paragraph.

 URL `http://ergoemacs.org/emacs/emacs_keybinding_design_beginning-of-line-or-block.html'
 Version 2017-01-17"
   (interactive)
   (if (or (equal (point) (line-beginning-position))
           (equal last-command this-command ))
	(if (re-search-backward "\n[\t\n ]*\n+" nil "NOERROR")
           (skip-chars-backward "\n\t ")
         (goto-char (point-min)))
     (beginning-of-line)))


 (defun xah-end-of-line-or-block ()
   "Move cursor to end of line, or end of current or next text block.

 • When called first time, move cursor to end of line.
 • When called again, move cursor to end of paragraph.
 • When called again, move cursor to end of next paragraph.

 URL `http://ergoemacs.org/emacs/emacs_keybinding_design_beginning-of-line-or-block.html'
 Version 2017-01-17"
   (interactive)
   (if (or (equal (point) (line-end-position))
           (equal last-command this-command ))
	(re-search-forward "\n[\t\n ]*\n+" nil "NOERROR" )
     (end-of-line)))

 (global-set-key (kbd "s-a") 'xah-beginning-of-line-or-block)
 (global-set-key (kbd "s-e") 'xah-end-of-line-or-block)

move lines

[2014-11-11 Tue 12:24]

M-p and M-n to move current line up or down.

(defun bba/move-line (n)
  "Move the current line up or down by N lines."
  (interactive "p")
  (let* ((column (current-column))
         (start (progn (beginning-of-line) (point)))
         (end (progn (end-of-line) (forward-char) (point)))
         (line-text (delete-and-extract-region start end)))
    (forward-line n)
    (insert line-text)
    (forward-line -1)
    (forward-char column)))

(defun bba/move-line-up (n)
  "Move the current line up by N lines."
  (interactive "p")
  (bba/move-line (if (null n) -1 (- n))))

(defun bba/move-line-down (n)
  "Move the current line down by N lines."
  (interactive "p")
  (bba/move-line (if (null n) 1 n)))

(define-key global-map (kbd "M-p") 'bba/move-line-up)
(global-set-key (kbd "M-n") 'bba/move-line-down)

xah-copy-line-or-region

[2017-03-17 Fri 14:07]

 (defun xah-copy-line-or-region ()
   "Copy current line, or text selection.
 When called repeatedly, append copy subsequent lines.
 When `universal-argument' is called first, copy whole buffer (respects `narrow-to-region').

 URL `http://ergoemacs.org/emacs/emacs_copy_cut_current_line.html'
 Version 2016-06-18"
   (interactive)
   (let (-p1 -p2)
     (if current-prefix-arg
         (setq -p1 (point-min) -p2 (point-max))
	(if (use-region-p)
           (setq -p1 (region-beginning) -p2 (region-end))
         (setq -p1 (line-beginning-position) -p2 (line-end-position))))
     (if (eq last-command this-command)
         (progn
           (progn ; hack. exit if there's no more next line
             (end-of-line)
             (forward-char)
             (backward-char))
           ;; (push-mark (point) "NOMSG" "ACTIVATE")
           (kill-append "\n" nil)
           (kill-append (buffer-substring-no-properties (line-beginning-position) (line-end-position)) nil)
           (message "Line copy appended"))
	(progn
         (kill-ring-save -p1 -p2)
         (if current-prefix-arg
             (message "Buffer text copied")
           (message "Text copied"))))
     (if (not (use-region-p))
	  (progn
	    (end-of-line)
	    (forward-char))
     )))

 (define-key global-map (kbd "M-w") 'xah-copy-line-or-region)

Xah Lee Move cursor to Bracket

[2017-03-27 Mon 22:41]

 (defvar xah-brackets nil "string of left/right brackets pairs.")
 (setq xah-brackets "()[]{}<>()[]{}⦅⦆〚〛⦃⦄“”‘’‹›«»「」〈〉《》【】〔〕⦗⦘『』〖〗〘〙「」⟦⟧⟨⟩⟪⟫⟮⟯⟬⟭⌈⌉⌊⌋⦇⦈⦉⦊❛❜❝❞❨❩❪❫❴❵❬❭❮❯❰❱❲❳〈〉⦑⦒⧼⧽﹙﹚﹛﹜﹝﹞⁽⁾₍₎⦋⦌⦍⦎⦏⦐⁅⁆⸢⸣⸤⸥⟅⟆⦓⦔⦕⦖⸦⸧⸨⸩⦅⦆⧘⧙⧚⧛⸜⸝⸌⸍⸂⸃⸄⸅⸉⸊᚛᚜༺༻༼༽⏜⏝⎴⎵⏞⏟⏠⏡﹁﹂﹃﹄︹︺︻︼︗︘︿﹀︽︾﹇﹈︷︸")

 (defvar xah-left-brackets '("(" "{" "[" "<" "" "" "" "" "" "" "" "" "" "" "«" )
   "List of left bracket chars.")
 (progn
 ;; make xah-left-brackets based on xah-brackets
   (setq xah-left-brackets '())
   (dotimes (-x (- (length xah-brackets) 1))
     (when (= (% -x 2) 0)
	(push (char-to-string (elt xah-brackets -x))
             xah-left-brackets)))
   (setq xah-left-brackets (reverse xah-left-brackets)))

 (defvar xah-right-brackets '(")" "]" "}" ">" "" "" "" "" "" "" "" "" "" "" "»")
   "list of right bracket chars.")
 (progn
   (setq xah-right-brackets '())
   (dotimes (-x (- (length xah-brackets) 1))
     (when (= (% -x 2) 1)
	(push (char-to-string (elt xah-brackets -x))
             xah-right-brackets)))
   (setq xah-right-brackets (reverse xah-right-brackets)))

 (defun xah-backward-left-bracket ()
   "Move cursor to the previous occurrence of left bracket.
 The list of brackets to jump to is defined by `xah-left-brackets'.
 URL `http://ergoemacs.org/emacs/emacs_navigating_keys_for_brackets.html'
 Version 2015-10-01"
   (interactive)
   (search-backward-regexp (regexp-opt xah-left-brackets) nil t))

 (defun xah-forward-right-bracket ()
   "Move cursor to the next occurrence of right bracket.
 The list of brackets to jump to is defined by `xah-right-brackets'.
 URL `http://ergoemacs.org/emacs/emacs_navigating_keys_for_brackets.html'
 Version 2015-10-01"
   (interactive)
   (re-search-forward (regexp-opt xah-right-brackets) nil t))

 (define-key global-map (kbd "s-,") 'xah-backward-left-bracket)
 (define-key global-map (kbd "s-.") 'xah-forward-right-bracket)

copy buffer file name to kill ring

Sometimes you need the filename of your current buffer on the command line or somewhere else.

(defun bba-copy-buffer-name ()
  "copy buffer name to kill-ring. if `universal-argument` is called first, copy only filename to kill-ring."
  (interactive)
  (let* ((bba-buffer-name (if current-prefix-arg (file-name-nondirectory (buffer-file-name))
			      (buffer-file-name)
			      )))
    (kill-new bba-buffer-name)
  (message ( format "stored '%s' in kill-ring" bba-buffer-name))
  ))

remove element from kill-ring

[2017-02-15 Wed 11:59]

sometimes you have credentials or other secret stuff in your kill-ring. savehist is nice but you don’t want to store it in the history.

(defun bba-rm-kill-ring ()
"remove current element from kill-ring."
(interactive)
(progn (pop kill-ring) nil)
(message  "removed item from kill-ring")
)

(defun bba-yank-rm-kill-ring ()
"yank and then remove element from kill ring"
(interactive)
(insert (pop kill-ring))
)
(define-key global-map (kbd "s-y") 'bba-yank-rm-kill-ring)
(define-key global-map (kbd "s-Y") 'bba-rm-kill-ring)

ggtags

Configure ggtags and helm-gtags to use GNU Global. If you are new to tags check this.

(if (>= emacs-major-version 24)
    (progn
      (add-to-list 'load-path "~/.emacs.d/elpa/ggtags-20181221.238" t)
      (require 'ggtags)
      (add-to-list 'load-path "~/.emacs.d/elpa/helm-gtags-20170116.529" t)
      (require 'helm-gtags)
      (add-hook 'puppet-mode-hook
                (lambda()
                  (if (locate-dominating-file (file-name-directory buffer-file-name) "GTAGS")
                      (ggtags-mode 1)
                    (helm-gtags-mode 1))))
      (add-hook 'python-mode-hook
                (lambda()
                  (if (locate-dominating-file (file-name-directory buffer-file-name) "GTAGS")
                      (ggtags-mode 1)
                    (helm-gtags-mode 1))))
      (add-hook 'cperl-mode-hook
                (lambda()
                  (if (locate-dominating-file (file-name-directory buffer-file-name) "GTAGS")
                      (ggtags-mode 1)
                    (helm-gtags-mode 1))))
      ))

helm

Some links you might check out:

 (if (>= emacs-major-version 24)
     (progn
	(add-to-list 'load-path
                    "~/.emacs.d/elpa/helm-20190122.549")
	(require 'helm)
	(helm-mode 1)
	(global-set-key (kbd "M-y") 'helm-show-kill-ring)
	(global-set-key (kbd "C-c w") 'helm-man-woman)
	(global-set-key (kbd "M-x") 'helm-M-x)
	(global-set-key "\C-cr" 'helm-recentf)
	(global-set-key (kbd "M-s o") 'helm-occur)
	(define-key global-map "\C-x\C-b" 'helm-buffers-list)
	(define-key global-map "\C-x\C-k\C-h" 'helm-execute-kmacro)
	(define-key global-map (kbd "C-x r b") 'helm-bookmarks)
	(define-key global-map (kbd "C-x C-S-f") 'helm-find-files)
	(define-key global-map "\C-cy" 'helm-yas-complete)
     (define-key org-mode-map "\C-ci" 'helm-org-in-buffer-headings)
	(setq helm-yas-display-key-on-candidate t)
	(setq helm-buffer-max-length nil)

	(add-hook 'eshell-mode-hook
                 #'(lambda()
                     (define-key eshell-mode-map
			[remap eshell-pcomplete]
			'helm-esh-pcomplete)
                     (define-key eshell-mode-map
			(kbd "M-p")
			'helm-eshell-history)
                     ))
	(add-hook 'shell-mode-hook
                 #'(lambda()
                     (define-key shell-mode-map
			[remap comint-history-isearch-backward-regexp]
			'helm-comint-input-ring)
                     ))
	(setq helm-mini-default-sources '(helm-source-buffers-list
                                         helm-source-recentf
                                         helm-source-bookmarks
                                         helm-source-buffer-not-found))
	(define-key global-map "\C-xb" 'helm-mini)
	)
 )

helm-descbinds

(if (>= emacs-major-version 24)
    (progn
      (add-to-list 'load-path "~/.emacs.d/elpa/helm-descbinds-20180429.1456")
      (require 'helm-descbinds)
      (define-key global-map (kbd "C-h b") 'helm-descbinds)
      )
)

browser switch

switch default browser between eww and default.

(defun bba-switch-default-browser ()
    "switch between default browser and eww"
  (interactive)
  (if (string-equal "browse-url-default-browser" browse-url-browser-function)
      (setq browse-url-browser-function 'eww-browse-url)
    (setq browse-url-browser-function 'browse-url-default-browser)
    )
  (message "%s" browse-url-browser-function)
  )

key-chord

combine key strokes to access commands even faster.

(add-to-list 'load-path "~/.emacs.d/elpa/key-chord-20160227.1238")

(require 'key-chord)
(key-chord-mode 1)
(setq key-chord-two-keys-delay 0.42)
(key-chord-define cfengine3-mode-map ";;" "\C-e;")
(key-chord-define cfengine3-mode-map ",," "\C-e,")
(key-chord-define prog-mode-map ";;" "\C-e;")
(key-chord-define prog-mode-map ",," "\C-e,")
(key-chord-define-global "uu" 'undo)
(key-chord-define-global "xb" 'helm-mini)
(key-chord-define-global "xf" 'ido-find-file)
(key-chord-define-global "xx" 'helm-M-x)
(key-chord-define org-mode-map "TT" 'org-set-tags)


keyfreq

[2016-11-23 Wed 13:33]

(add-to-list 'load-path "~/.emacs.d/elpa/keyfreq-20160516.1416")
(require 'keyfreq)
(keyfreq-mode 1)
(keyfreq-autosave-mode 1)

no-rsi

[2016-12-06 Tue 10:35]

(setq type-break-keystroke-threshold '(3600 . 18000))
(type-break-mode t)

aliases

(defalias 'ts 'transpose-sentences)
(defalias 'tp 'transpose-paragraphs)
(defalias 'om 'org-mode)
(defalias 'vsql 'sql-vertica)
(defalias 'mysql 'sql-mysql)

smart comma

Thanks to Marcin Borkowski for this code snippet.

(defun smart-self-insert-punctuation (count)
  "If COUNT=1 and the point is after a space, insert the relevant
character before any spaces."
  (interactive "p")
  (if (and (= count 1)
           (eq (char-before) ?\s))
      (save-excursion
        (skip-chars-backward " ")
        (self-insert-command 1))
    (self-insert-command count)))

(global-set-key "," #'smart-self-insert-punctuation)

key bindings

(define-key global-map (kbd "M-@") 'cycle-spacing)
(define-key global-map (kbd "M-SPC") 'cycle-spacing)
(define-key global-map (kbd "s-r") 'repeat)
(define-key global-map "\C-x\S-f" 'find-file-at-point)

(define-key global-map "\C-c\S-t" 'visit-tags-table)
(define-key global-map "\C-cf" 'tags-search)

(define-key global-map (kbd "s-b") 'clone-indirect-buffer)

(define-key global-map (kbd "C-c M-s") 'string-edit-at-point)

(define-key global-map "\C-cp" 'org-mark-ring-push)
(define-key global-map "\C-cn" 'org-mark-ring-goto)

(define-prefix-command 'bba/toggle)
(define-key global-map "\C-ct" 'bba/toggle)

(define-key bba/toggle "\S-a" 'abbrev-mode)
(define-key bba/toggle "a" 'artbollocks-mode)
(define-key bba/toggle "b" 'bba-switch-default-browser)
(define-key bba/toggle "c" 'rainbow-mode)
(define-key bba/toggle "\S-c" 'bba-toggle-copyright-update)
(define-key bba/toggle "e" 'eldoc-mode)
(define-key bba/toggle "\S-e" 'epoch-view-mode)
(define-key bba/toggle "f" 'auto-fill-mode)
(define-key bba/toggle "\S-f" 'follow-mode)
(define-key bba/toggle "h" 'highlight-indentation-mode)
(define-key bba/toggle "\S-h" 'highlight-indentation-current-column-mode)
(define-key bba/toggle "\C-h" 'hl-line-mode)
(define-key bba/toggle "\M-h" 'highlight-symbol-mode)
(define-key bba/toggle "i" 'impatient-mode)
(define-key bba/toggle "p" 'smartparens-mode)
(define-key bba/toggle "r" 'rainbow-delimiters-mode)
(define-key bba/toggle "s" 'flyspell-mode)
(define-key bba/toggle (kbd "s-s") 'stripes-mode)
(define-key bba/toggle "\S-s" 'smerge-mode)
(define-key bba/toggle "t" 'toggle-truncate-lines)
(define-key bba/toggle "v" 'visual-line-mode)
(define-key bba/toggle "\S-w" 'which-function-mode)

(define-key dired-mode-map "/" 'dired-narrow-regexp)

easy access to secrets.

(define-prefix-command 'bba/pw)
(define-key global-map "\C-xp" bba/pw)
(define-key bba/pw "p" '(lambda () "awsprod" (interactive)(bba-pw-lookup "0DA39906-79C8-4468-AB0A-C72DB613C529")))
(define-key bba/pw "t" '(lambda () "awstest" (interactive)(bba-pw-lookup "D0518F8B-C724-45B8-8D85-C568DCDD5913")))
(define-key bba/pw "c" '(lambda () "awscn" (interactive)(bba-pw-lookup "53D5B091-0295-42BA-9D91-4A36055E554B")))
(define-key bba/pw "s" '(lambda () "sys" (interactive)(bba-pw-lookup "FABC2AFA-E966-4AC3-AEEB-2883DE790DE4")))
(define-key bba/pw "S" '(lambda () "ssh" (interactive)(bba-pw-lookup "BF852AE1-57B7-4C7F-BE02-F73095D4CD52")))
(define-key bba/pw "i" '(lambda () "it" (interactive)(bba-pw-lookup "83752B2C-5DE4-4B2F-A306-B191348A2E26")))


(defun bba-pw-lookup (id)
  "lookup org id and grab hide-pw entry"
  (interactive)
  (org-id-goto id)
  (if (invisible-p (point-at-eol))
      (org-cycle))
  (if (re-search-forward "^||")
      (progn
        (set-mark-command nil)
        (org-end-of-line)
        (backward-char 2)
        (kill-ring-save 1 1 1)
        (org-previous-visible-heading 1)
        (org-end-of-line)
        (org-beginning-of-line))))

duplicate previous line

(global-set-key (kbd "s-d") "\C-p\C-a\C- \C-n\M-w\C-y")

Toggle Whitespace mode on and off. Whitespace mode causes all hard tabs to be highlighted. You can also configure it to highlight space characters in a different color. There is also an untabify function to convert hard tabs to the appropriate number of spaces, and a tabify function to convert groups of spaces to hard tabs.

(define-key bba/toggle "w" 'whitespace-mode)

(setq whitespace-display-mappings
       ;; all numbers are Unicode codepoint in decimal. try (insert-char 182 ) to see it
      '(
        (space-mark 32 [183] [46]) ; 32 SPACE, 183 MIDDLE DOT 「·」, 46 FULL STOP 「.」
        (newline-mark 10 [182 10]) ; 10 LINE FEED
        (tab-mark 9 [9655 9] [92 9]) ; 9 TAB, 9655 WHITE RIGHT-POINTING TRIANGLE 「▷」
        ))
(define-prefix-command 'bba/launcher)
(define-key global-map "\C-xl" 'bba/launcher)

(define-key bba/launcher "!" 'eshell-here)
(define-key bba/launcher "b" 'browse-url-at-point)
(define-key bba/launcher "B" 'eww)
(define-key bba/launcher "\C-b" 'helm-safari-bookmarks)
(define-key bba/launcher "\C-h" 'helm-safari-history)
(define-key bba/launcher "c" 'helm-calcul-expression)
(define-key bba/launcher "d" 'ediff-buffers)
(define-key bba/launcher "e" 'eshell)
(define-key bba/launcher "E" 'elfeed)
(define-key bba/launcher "i" 'ielm)
(define-key bba/launcher "k" 'bba/keyboard-maestro)
(define-key bba/launcher "l" 'magit-log-buffer-file)
(define-key bba/launcher "m" 'bba/multiple-cursors)
(define-key bba/launcher "n" 'neotree)
(define-key bba/launcher "o" 'bba-open-file-dir-finder)
(define-key bba/launcher "s" 'shell)
(define-key bba/launcher "S" 'synonyms)
(define-key bba/launcher "\C-s" 'helm-swoop)
(define-key bba/launcher "t" 'git-timemachine)
(define-key bba/launcher "T" 'twittering-mode)

(define-prefix-command 'bba/keyboard-maestro)
(define-prefix-command 'bba/multiple-cursors)

(define-key bba/keyboard-maestro "s" 'bba-screen-start-ssh-to-fqdn-at-point)
(define-key bba/keyboard-maestro "\C-s" 'bba-splunk-search)
(define-key bba/keyboard-maestro "c" 'bba-open-file-dir-screen)
(define-key bba/keyboard-maestro "C" 'bba-create-ticket-tmp-dir-open-dir-screen)

(define-key bba/multiple-cursors "e" 'mc/edit-lines)
(define-key bba/multiple-cursors "m" 'mc/mark-all-like-this)
(define-key bba/multiple-cursors "n" 'mc/mark-next-like-this)
(global-unset-key (kbd "M-<down-mouse-1>"))
(global-set-key (kbd "M-<mouse-1>") 'mc/add-cursor-on-click)
(define-key global-map "\C-c\C-t" 'insert-timestamp)
(define-key global-map "\C-c\M-c" 'centered-cursor-mode)

(define-key global-map "\C-ci" 'imenu)
(define-key global-map "\C-c\S-g" 'rgrep)
(define-key global-map "\C-cf" 'load-git-cfengine)

(define-key global-map "\C-c\C-w" 'fixup-whitespace)

(define-key global-map "\M-g\M-d" 'magit-diff-unstaged)
(define-key global-map "\M-g\S-d" '(lambda()
                                   (interactive)
                                   (call-interactively 'magit-file-delete)
                                   (kill-buffer)
                                   )
  )
(define-key global-map "\M-g\M-b" 'magit-branch-manager)
(define-key global-map "\M-gb" 'magit-blame-popup)
(define-key global-map "\C-cm" 'magit-status)
(global-set-key (kbd "C-c s-m") 'magit-list-repositories)

(define-key global-map "\C-c\S-f" (lambda()
                                 (interactive)
                                 (message (buffer-file-name))))
(define-key global-map (kbd "C-c C-S-f") 'bba-copy-buffer-name)
(if (<= emacs-major-version 23)
    (progn
      (define-key global-map "\C-cw" (lambda ()
                                       (interactive)
                                       (let ((woman-use-topic-at-point t))
                                         (woman))))
      (define-key global-map "\C-x\C-b" 'ibuffer)
      )
)

(define-key global-map "\C-c\M-d" 'diff-buffer-with-file)

;;; ** Use C-+ and C-- to adjust font size

(define-key global-map (kbd "C-+") 'text-scale-increase)
(define-key global-map (kbd "C--") 'text-scale-decrease)


isearch-forward-regexp is much more useful than isearch-forward so we use that as default:

(global-set-key (kbd "C-s") 'isearch-forward-regexp)
(global-set-key (kbd "C-r") 'isearch-backward-regexp)
(global-set-key (kbd "C-M-s") 'isearch-forward)
(global-set-key (kbd "C-M-r") 'isearch-backward)

Thanks to Xah Lee for this:

Here’s very convenient keys for isearch.

(define-key isearch-mode-map (kbd "<up>") 'isearch-ring-retreat )
(define-key isearch-mode-map (kbd "<down>") 'isearch-ring-advance )

(define-key isearch-mode-map (kbd "<left>") 'isearch-repeat-backward)
(define-key isearch-mode-map (kbd "<right>") 'isearch-repeat-forward)

(define-key minibuffer-local-isearch-map (kbd "<left>") 'isearch-reverse-exit-minibuffer)
(define-key minibuffer-local-isearch-map (kbd "<right>") 'isearch-forward-exit-minibuffer)

Adjust mouse speed:

(setq mouse-wheel-scroll-amount '(1 ((shift) . 1) ((control) . nil)))
(setq mouse-wheel-progressive-speed nil)

By indentation

Borrowed from github:

C-a normally moves us to the beginning of the line unconditionally with move-beginning-of-line. This version is more useful, as it moves to the first non-whitespace character if we’re already at the beginning of the line. Repeated use of `C-a’ toggles between these two positions.

(defun beginning-of-line-dwim ()
  "Toggles between moving point to the first non-whitespace character, and
the start of the line."
  (interactive)
  (let ((start-position (point)))
    ;; Move to the first non-whitespace character.
    (back-to-indentation)

    ;; If we haven't moved position, go to start of the line.
    (when (= (point) start-position)
      (move-beginning-of-line nil))))

(global-set-key (kbd "C-a") 'beginning-of-line-dwim)

Beautifying JSON

(defun beautify-json ()
"Use python to prettyprint JSON."
  (interactive)
  (let ((b (if mark-active (min (point) (mark)) (point-min)))
        (e (if mark-active (max (point) (mark)) (point-max))))
    (shell-command-on-region b e
     "python2.7 -mjson.tool" (current-buffer) t)))

words-speak

[2016-12-18 Sun 15:11]

(defvar words-voice "Vicki"
  "Mac voice to use for speaking.")

(defun words-speak (&optional text)
  "Speak word at point or region. Mac only."
  (interactive)
  (require 'json)
  (unless text
    (setq text (if (use-region-p)
                   (buffer-substring
                    (region-beginning) (region-end))
                 (thing-at-point 'word))))
  ;; escape some special applescript chars
  (setq text (replace-regexp-in-string "\\\\" "\\\\\\\\" text))
  (setq text (replace-regexp-in-string "\"" "\\\\\"" text))
  (do-applescript
   (format
    "say \"%s\" using \"%s\""
    text
    words-voice)))

kill this buffer

[2016-09-26 Mon 13:22]

Kill the current buffer without asking if there is no prefix.

 (defun jcs-kill-a-buffer (askp)
   (interactive "P")
   (if askp
	(kill-buffer (funcall completing-read-function
                             "Kill buffer: "
                             (mapcar #'buffer-name (buffer-list))))
     (kill-this-buffer)))

 (global-set-key (kbd "C-x k") 'jcs-kill-a-buffer)

ediff marked pair

[2016-10-17 Mon 11:57]

Had to diff files on 2 different servers. What’s better then dired and TRAMP?

(defun mkm/ediff-marked-pair ()
   "Run ediff-files on a pair of files marked in dired buffer"
   (interactive)
   (let* ((marked-files (dired-get-marked-files nil nil))
          (other-win (get-window-with-predicate
                      (lambda (window)
                        (with-current-buffer (window-buffer window)
                          (and (not (eq window (selected-window)))
                               (eq major-mode 'dired-mode))))))
          (other-marked-files (and other-win
                                   (with-current-buffer (window-buffer other-win)
                                     (dired-get-marked-files nil)))))
     (cond ((= (length marked-files) 2)
            (ediff-files (nth 0 marked-files)
                         (nth 1 marked-files)))
           ((and (= (length marked-files) 1)
                 (= (length other-marked-files) 1))
            (ediff-files (nth 0 marked-files)
                         (nth 0 other-marked-files)))
           ((= (length marked-files) 1)
            (let ((single-file (nth 0 marked-files)))
              (ediff-files single-file
                           (read-file-name
                            (format "Diff %s with: " single-file)
                            nil (m (if (string= single-file (dired-get-filename))
                                       nil
                                     (dired-get-filename))) t))))
           (t (error "mark no more than 2 files")))))



    (add-hook 'dired-mode-hook
              (lambda ()
                ;; The 'ls' executable requires the Gnu version on the Mac
                (define-key dired-mode-map "=" 'mkm/ediff-marked-pair)))

Get keychain password

[2016-10-21 Fri 13:31]

If I’m on OS X, I can fetch passwords etc. from my Keychain. This is much more secure than storing them in configuration on disk:

(defun bw/chomp (str)
  "Chomp leading and tailing whitespace from `str'."
  (while (string-match "\\`\n+\\|^\\s-+\\|\\s-+$\\|\n+\\'" str)
    (setq str (replace-match "" t t str))) str)

(defun bw/get-keychain-password (account-name)
  "Get `account-name' keychain password from OS X Keychain"
  (interactive "sAccount name: ")
  (when (executable-find "security")
    (bw/chomp
     (shell-command-to-string
      (concat
       "security find-generic-password -wa "
       account-name)))))

hide minor modes

[2017-01-30 Mon 16:28]

We don’t need all minor modes listed in the modeline.

 (defvar hidden-minor-modes ; example, write your own list of hidden
   '(abbrev-mode            ; minor modes
     auto-fill-function
     auto-complete-mode
     inf-haskell-mode
     haskell-indent-mode
     haskell-doc-mode
     smooth-scroll-mode
     hidepw-mode
     helm-mode
     undo-tree-mode
     guide-key-mode
     artbollocks-mode
     ))

 (defun purge-minor-modes ()
   (interactive)
   (dolist (x hidden-minor-modes nil)
     (let ((trg (cdr (assoc x minor-mode-alist))))
	(when trg
	  (setcar trg "")))))

 (add-hook 'after-change-major-mode-hook 'purge-minor-modes)

configure some default values

[2014-10-02 Thu 00:27]

Specify printing format

(setq ps-paper-type 'a4)

compilation output

(setq compilation-scroll-output 'first-error)

Set ispell dictionary

(setq ispell-dictionary "english")

Set shell for M-| command

(setq shell-file-name "/bin/bash")

Set Shell used by TeX

(setq tex-shell-file-name "/bin/bash")

Set grep command options

(setq grep-command "grep -i -nH -e ")

Give your cursor some context.

(setq scroll-margin 3)

Confirm quit to avoid hitting C-x C-c by accident.

(setq confirm-kill-emacs 'yes-or-no-p)

Confirm suspend to avoid suspending by accident.

(put 'suspend-frame 'disabled t)

Ignore case when completing file names

(setq read-file-name-completion-ignore-case t)

Highlight parenthesis pairs

(show-paren-mode 1)

Blinking parenthesis

(setq blink-matching-paren-distance nil)

Highlight text between parens

(setq show-paren-style 'expression)

Use buffer name as frame title

(setq frame-title-format "%b - emacs")

Completion in mini-buffer

(icomplete-mode t)

Stack minibuffers

(setq enable-recursive-minibuffers t)

Make dired human readable

(setq dired-listing-switches "-alh")

Guess copy target. If split window use others current directory.

(setq dired-dwim-target t)

Dired isn’t very colourful by default, but `dired+’ has helpful highlighting.

(setq diredp-hide-details-initially-flag nil)
(require 'dired+)
(setq ediff-split-window-function 'split-window-horizontally)

use smtp for sending emails. set your mailserver settings outside of this file.

(setq smtpmail-smtp-server "your.mailserver")
(setq smtpmail-smtp-service "25")
(setq send-mail-function 'smtpmail-send-it)

Some nice functions

;;(blink-matching-paren 1)
;;(paren-activate)

XML indentation

(if (equal "work" (getenv "SYSENV"))
    (setq nxml-child-indent 4))

update copyrights

(defvar bba-copyright-update 't)
(defun bba-toggle-copyright-update()
  "switch copyright-update on save on or off."
  (interactive)
  (if (bound-and-true-p bba-copyright-update)
      (setq bba-copyright-update nil)
    (setq bba-copyright-update t))
  (message "copyright-update is %s" bba-copyright-update)
  )
(add-hook 'before-save-hook (lambda()
                                   (if (bound-and-true-p bba-copyright-update)
                                       (copyright-update))))

other stuff

;;(move-overlay hl-line-overlay
;;            (line-beginning-position) (1+ (line-end-position))
;;            (current-buffer))

;; (set-face-background-pixmap 'default "~/.emacs.d/xemacs-bg.xpm")
(set-foreground-color "green")
(set-background-color "black")

;; pos1: goto start of line, start of screen, start of buffer
;; end: goto end of line, end of screen, end of buffer

(global-set-key '[(home)] 'chb-home)
(global-set-key '[(end)] 'chb-end)
;;
(defun chb-home ()
  (interactive)
  (if (not (bolp))
      (beginning-of-line)
    (if (eq this-command last-command)
        (cond
         ((not (= (point) (window-start)))
          (move-to-window-line 0)
          (beginning-of-line))
         (t
          (goto-char (point-min)))))))

(defun chb-end ()
  (interactive)
  (if (not (eolp))
      (end-of-line)
    (if (eq this-command last-command)
        (cond
         ((not (= (point) (save-excursion
                            (move-to-window-line -1)
                            (end-of-line)
                            (point))))
          (move-to-window-line -1)
          (end-of-line))
         (t
          (goto-char (point-max)))))))



Make the window title display the full path of the file I’m currently editing:

(when (display-graphic-p)
  (setq frame-title-format
        '((:eval (if (buffer-file-name)
                     (abbreviate-file-name (buffer-file-name))
                   "%b")))))

sRGB display fixes

(setq ns-use-srgb-colorspace t)

There are a few applications, such as crontab, that require a trailing new line. To be safe, always leave a trailing newline.

(setq-default require-final-newline t)

You have to work hard to be lazy.

(defalias 'ts 'transpose-sentences)
(defalias 'tp 'transpose-paragraphs)

Save whatever’s in the current (system) clipboard before replacing it with the Emacs’ text. https://github.com/dakrone/eos/blob/master/eos.org

(setq save-interprogram-paste-before-kill t)

editorconfig

[2017-01-06 Fri 14:27]

Set default indentation, end of line, trailing whitespaces etc for the whole team. No matter what editor gets used.

(if (equal "work" (getenv "SYSENV"))
    (editorconfig-mode '1))

set theme bba1

Emacs Theme Editor is a nice tool to define your colors.

  (deftheme bba1 "DOCSTRING for bba1")
    (custom-theme-set-faces 'bba1
     '(default ((t (:foreground "#07e30d" :background "#282828" ))))
     '(cursor ((t (:background "#f09213" ))))
     '(fringe ((t (:background "#131313" ))))
     '(mode-line ((t (:foreground "#282828" :background "#d96503" ))))
     '(region ((t (:background "#7a7674" ))))
     '(secondary-selection ((t (:background "#584e47" ))))
     '(font-lock-builtin-face ((t (:foreground "#fe8019" ))))
     '(font-lock-comment-face ((t (:foreground "#df7114" ))))
     '(font-lock-function-name-face ((t (:foreground "#b8bb26" ))))
     '(font-lock-keyword-face ((t (:foreground "#fb4934" ))))
     '(font-lock-string-face ((t (:foreground "#b8bb26" ))))
     '(font-lock-type-face ((t (:foreground "#d3869b" ))))
     '(font-lock-constant-face ((t (:foreground "#d3869b" ))))
     '(font-lock-variable-name-face ((t (:foreground "#83a598" ))))
     '(minibuffer-prompt ((t (:foreground "#b8bb26" :bold t ))))
     '(font-lock-warning-face ((t (:foreground "red" :bold t ))))
     )
  (provide-theme 'bba1)

 (if (display-graphic-p)
     (progn
	(custom-set-faces
	 '(org-block-begin-line ((t (:background "#07538a" :foreground "#84cbef"))) t)
	 '(org-block-end-line ((t (:inherit org-block-begin-line))) t)
	 '(org-block ((t (:inherit shadow :background "#29759c" :foreground "#84cbef" :distant-forground "#131313"))))
	 ;; '(show-paren-match ((t (:distant-foreground "#29759c":background "#84cbef" ))))
	 ;;'(show-paren-match ((t (:inverse-video t))))
      '(show-paren-match ((t (:underline (:color "#07e30d" :style line)))))
      '(show-paren-mismatch ((t (:underline (:color "red" :style wave)))))
	 ;; '(show-paren-match ((t (:unterline (:color "#b8bb26" :style wave)))))
	 )
	(let* ((variable-tuple (cond ((x-list-fonts "Arial") '(:font "Arial"))
                                    ((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.  Install Source Sans Pro."))))
              (base-font-color     (face-foreground 'default nil 'default))
              (headline           `(:inherit default :foreground "#62a9cd")))

         (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.4))))
                                 `(org-level-1 ((t (,@headline ,@variable-tuple :height 1.6))))
                                 `(org-document-title ((t (,@headline ,@variable-tuple :height 1.5 :underline nil)))))
	  (custom-set-variables
	    '(ansi-color-names-vector
	      ["black" "red3" "green3" "yellow3" "LightSkyBlue1" "magenta3" "cyan3" "gray90"]))
	  )))

load custom file

[2014-10-02 Thu 00:37]

  (setq custom-file
        (expand-file-name "custom.el"
                          (expand-file-name ".emacs.d" "~")))
;;  (load-file user-init-file)
  (load-file custom-file)

Set default font on Mac

(if (string-equal system-type "darwin")
 (set-frame-font "Menlo 12"))

dns-mode

If you edit zone files via TRAMP you might want to activate them via rndc reload. C-c C-r just does that for you.

(defun dns-rndc ()
"Do rndc reload of current buffers filename."
(interactive)
(string-match "/\\([^/]*\\)$" buffer-file-name)
(let* ((zonefile (match-string 1 buffer-file-name))
       )
  (if (y-or-n-p (format "rndc reload %s?" zonefile))
      (shell-command (concat "rndc reload " zonefile ) ) )
  )

)

(eval-after-load 'dns-mode
  (add-hook 'dns-mode-hook
           (lambda ()
             (define-key dns-mode-map "\C-c\C-r" 'dns-rndc)
             )))

save history

[2015-04-05 Sun 12:57]

Write a history of your emacs into your org git repository. You have it available on every system and it’s still private at it’s not in the public git emacs configuration.

  • kill ring
  • search ring
  • regexp-search-ring
  • last-kbd-macro
  • kmacro-ring
  • shell-command-history

all in your history.

 (setq savehist-additional-variables '(kill-ring search-ring regexp-search-ring last-kbd-macro kmacro-ring shell-command-history))
 (setq kmacro-ring-max 42)
 (setq history-delete-duplicates t)
 (if (equal "work" (getenv "SYSENV"))
     (if (file-exists-p "~/workorg")
         (setq savehist-file "~/workorg/emacshistory")
	)
   (if (file-exists-p "~/org")
	(setq savehist-file "~/org/emacshistory")
     )
   (if (file-exists-p savehist-file)
	(load-file savehist-file)
	)

 )
 (savehist-mode 1)

start ssh in screen session

[2016-02-11 Thu 12:42]

This one uses Keyboard Maestro to launch a ssh in a screen session in iTerm2. Assumption clipboard is a dns name.

(defun bba-screen-start-ssh-to-clipboard (&optional arg)
"Use a macro in Keyboard Maestro to ssh into a system in iterm screen session."
(interactive)
(if arg
    (kill-new (thing-at-point arg))
  )
(shell-command "osascript -e \'tell app \"Keyboard Maestro Engine\" to do script \"screen-start-ssh-to-clipboard\"'" )
)

(defun bba-screen-start-ssh-to-fqdn-at-point()
  "run ssh to fqdn in screen session. fallback to clipboard."
  (interactive)
  (bba-screen-start-ssh-to-clipboard 'fqdn)
  )

aws

Use aws command line tool via Emacs.

(defun bba-aws-desc-instances ( profile name)
  "query aws to get informations for running instances."
  (interactive "sProfile: \nsName: ")
  (switch-to-buffer (concat "*aws-" profile "-" name "*"))
  (org-mode)
  (message "querying aws for %s in profile %s" name profile)
  (insert (shell-command-to-string (concat "aws ec2 describe-instances --profile " profile " --filters \"Name=tag-key,Values=Name,Name=tag-value,Values=" name "*\" --query \"Reservations[].Instances[?State.Name=='running'].[InstanceId, PublicDnsName]\" --output table")))
  (message "done.")
)

Check a AWS Cloudformation template with cfn_nag:

(defun bba-aws-cfn-nag-scan()
  "Check buffer with cfn_nag_scan."
  (interactive)
  (shell-command (concat "cfn_nag_scan --input-path " buffer-file-name)))
(define-key json-mode-map (kbd "C-c C-n") 'bba-aws-cfn-nag-scan)

Check a AWS Cloudformation template with cfn-lint:

(defun bba-aws-cfn-lint()
  "Check buffer with cfn_lint."
  (interactive)
  (shell-command (concat "cfn-lint " buffer-file-name)))
(define-key json-mode-map (kbd "C-c C-l") 'bba-aws-cfn-lint)

terraform

[2016-09-02 Fri 14:57]

(add-hook 'terraform-mode-hook #'terraform-format-on-save-mode)

thing-at-point-fqdn

[2016-02-12 Fri 14:13]

(defun fqdn-bounds-of-fqdn-at-point ()
     "Return the start and end points of an fqdn at the current point.
   The result is a paired list of character positions for an fqdn
   located at the current point in the current buffer."
     (save-excursion
       (skip-chars-backward "-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
       (if (looking-at "[-.0-9a-zA-Z]+")
           (cons (point) (match-end 0)) ; bounds of fqdn
         nil))) ; no fqdn at point

(put 'fqdn 'bounds-of-thing-at-point
       'fqdn-bounds-of-fqdn-at-point)

thing-at-point-instanceID

[2016-02-12 Fri 14:13]

Amazon instance ID at point.

(defun instanceid-bounds-of-instanceid-at-point ()
     "Return the start and end points of an Amazon instance ID at the current point.
   The result is a paired list of character positions for an fqdn
   located at the current point in the current buffer."
     (save-excursion
       (skip-chars-backward "-.0123456789abcdefi")
       (if (looking-at "i-[-.0-9abcdef]+")
           (cons (point) (match-end 0)) ; bounds of fqdn
         nil))) ; no fqdn at point

(put 'instanceid 'bounds-of-thing-at-point
       'instanceid-bounds-of-instanceid-at-point)

post

[2015-10-02 Fri 13:26]

Some private settings outside this repository are loaded after this configuration.

(if (file-exists-p "~/.emacs_post.el")
(load-file "~/.emacs_post.el"))

done

Display greetings:

(totd)
(switch-to-buffer "*Tip of the day*")
(delete-other-windows)
(message "All done, %s!" (user-login-name) )

Split and show workhours:

(if (equal "work" (getenv "SYSENV"))
  (progn (split-window-below)
         (other-window 1)
         (find-file "~/org/workhours.org")
         (goto-char (point-min))
         (org-shifttab 3)
	   (if (re-search-forward (concat "^\*\* "(format-time-string "%Y-%m")) nil t)
	       (org-beginning-of-line)
	     (progn
	       (goto-char (point-min))
	       (org-next-visible-heading '1)
	       (org-meta-return)
	       (insert (format-time-string "%Y-%m"))
	       ))
         ))

[2014-08-27 Wed 11:02]

old config




    (setq org-html-head "<style type=\"text/css\">
body {
    background-color: #bbbbbb;
}     </style>")


  body {
      background-color: #bbbbbb;
      color: #000000;
      margin: 0px;
      padding: 0px;
      height: 100%;
  }'



    ;;; * Big Brother Database

    ;; (require 'bbdb)
    ;; (bbdb-initialize)

    ;;; * auto-completion

    ;;(move-overlay hl-line-overlay
    ;;            (line-beginning-position) (1+ (line-end-position))
    ;;            (current-buffer))

    ;; (set-face-background-pixmap 'default "~/.emacs.d/xemacs-bg.xpm")
    (set-foreground-color "green")
    (set-background-color "black")

    ;; pos1: goto start of line, start of screen, start of buffer
    ;; end: goto end of line, end of screen, end of buffer

    (global-set-key '[(home)] 'chb-home)
    (global-set-key '[(end)] 'chb-end)
    ;;
    (defun chb-home ()
    (interactive)
    (setq zmacs-region-stays t)
    (if (not (bolp))
    (beginning-of-line)
    (if (eq this-command last-command)
    (cond
     ((not (= (point) (window-start)))
      (move-to-window-line 0)
      (beginning-of-line))
     (t
      (goto-char (point-min)))))))

    (defun chb-end ()
    (interactive)
    (setq zmacs-region-stays t)
    (if (not (eolp))
    (end-of-line)
    (if (eq this-command last-command)
    (cond
     ((not (= (point) (save-excursion
                        (move-to-window-line -1)
                                (end-of-line)
                                (point))))
              (move-to-window-line -1)
              (end-of-line))
             (t
              (goto-char (point-max)))))))




    ;; safe files with #! in first line as user executable

    (add-hook `after-safe-hook
              #'(lambda ()
                 (and (save-excursion
                        (save-restriction
                          (widen)
                          (goto-char (point-min))
                          (save-match-data
                            (looking-at "^#!"))))
                      (not (file-executable-p buffer-file-name))
                      (shell-command (concat "chmod u+x " buffer-file-name))
                      (message
                       (concat "Saved as script: " buffer-file-name)))))

    ;;
    ;; list of recently opened files
    ;;

    ;; (load "recent-files")
    ;; (setq recent-files-dont-include
    ;;      '("~$" "tmp/." "INBOX" ".bbdb" ".newsrc." ))

    ;; (setq recent-files-non-permanent-submenu t)
    ;; (setq recent-files-commands-submenu t)
    ;; (setq recent-files-number-of-entries 30)
    ;; (recent-files-initialize)

    ;;  Make the <ctrl> c F12 key toggle Whitespace mode on and off.  Whitespace mode causes
    ;; all hard tabs to be highlighted.  You can also configure it to highlight space characters
    ;; in a different color.  There is also an untabify function to convert hard tabs to the
    ;; appropriate number of spaces, and a tabify function to convert groups of spaces to
    ;; hard tabs.
    (global-set-key (kbd "C-c <f12>") 'whitespace-mode)


    ;; (add-hook 'find-file-hooks 'fume-setup-buffer)
    ;; (add-hook 'Manual-mode-hook 'turn-on-fume-mode)

    ;; (function-menu USE-MENUBAR RETURN-ONLY MENU-ITEM-FUNCTION)

    ;;====================================================================
    ;;The Following Code Will Enable Me To Use The "Fume" Package Which
    ;;Creates, On The Menubar, A "Functions" Menu Containing The List Of
    ;;All The Functions In The Buffer Being Currently Displayed.
    ;;====================================================================
    ;;
    ;;Setq-Default Set The Default Value Of A Var.  This Def. Val. Is Seen
    ;;In Buffers That *Don'T* Have Their Own Values For The Variable.

    ;(require function-menu)
    ;(Define-Key Global-Map 'F8 'Function-Menu)
    ;(Add-Hook 'Find-File-Hooks 'Fume-Add-Menubar-Entry)
    ;(Define-Key Global-Map "\C-Cl" 'Fume-List-Functions)
    ;(Define-Key Global-Map "\C-Cg" 'Fume-Prompt-Function-Goto)
    ;(Define-Key Global-Map '(Shift Button3) 'Mouse-Function-Menu)
    ;(Define-Key Global-Map '(Meta  Button1) 'Fume-Mouse-Function-Goto)

    ;(Add-Hook
    ; 'Find-File-Hooks
    ; (Function
    ;  (Lambda()
    ;    (If (And (String-Match "Xemacs" Emacs-Version)
    ;             (Boundp 'Emacs-Major-Version)
    ;            (Or (= Emacs-Major-Version 20)
    ;                 (And
    ;                  (= Emacs-Major-Version 19)
    ;                 (>= Emacs-Minor-Version 13)))
    ;             (Not (Eq Major-Mode 'Latex-Mode)))
    ;        (Fume-Add-Menubar-Entry))
    ;    )))


    (define-key global-map "\C-ct" 'visit-tags-table)
    (define-key global-map "\C-cf" 'tags-search)

    (define-key global-map "\C-c\C-t" 'insert-timestamp)
    (define-key global-map "\C-c\M-c" 'centered-cursor-mode)

    (define-key global-map "\C-cf" 'load-git-cfengine)

    (define-key global-map "\C-c\C-w" 'fixup-whitespace)


    (define-key global-map "\M-g\M-d" 'magit-diff-unstaged)
    (define-key global-map "\M-g\M-b" 'magit-branch-manager)
    (define-key global-map "\M-gb" 'magit-blame-mode)
    (define-key global-map "\C-cm" 'magit-status)

    (define-key global-map "\C-cw" (lambda ()
                                     (interactive)
                                     (let ((woman-use-topic-at-point t))
                                       (woman))))
    (define-key global-map "\C-c\M-d" 'diff-buffer-with-file)

    ;;; ** Use C-+ and C-- to adjust font size

    (define-key global-map (kbd "C-+") 'text-scale-increase)
    (define-key global-map (kbd "C--") 'text-scale-decrease)

    ;; NUMBERIC KEYPAD. nice number pad conveniences as extra function keys

    ;; (global-set-key (kbd "<kp-subtract>") 'ergoemacs-close-current-buffer)
    ;; (global-set-key (kbd "<kp-divide>") 'ergoemacs-previous-user-buffer)
    ;; (global-set-key (kbd "<kp-multiply>") 'ergoemacs-next-user-buffer)

    ;; (global-set-key (kbd "<C-kp-divide>") 'ergoemacs-previous-emacs-buffer)
    ;; (global-set-key (kbd "<C-kp-multiply>") 'ergoemacs-next-emacs-buffer)

    ;; (global-set-key (kbd "<kp-decimal>") 'other-window)
    ;; (global-set-key (kbd "<kp-0>") 'delete-window)
    ;; (global-set-key (kbd "<kp-1>") 'delete-other-windows)
    ;; (global-set-key (kbd "<kp-2>") 'split-window-vertically)
    ;; (global-set-key (kbd "<kp-3>") 'xah-open-file-at-cursor)

    ;; (global-set-key (kbd "<kp-9>") 'isearch-forward)

    (setq custom-file
          (expand-file-name "custom.el"
                            (expand-file-name ".emacs.d" "~")))
    (load-file user-init-file)
    (load-file custom-file)
You can’t perform that action at this time.