Inspired by this config and config of angrybacon.
(require 'package)
(add-to-list 'package-archives
'("melpa" . "https://melpa.org/packages/") t)
(add-to-list 'package-archives
'("nongnu" . "https://elpa.nongnu.org/nongnu/") t)
(unless (package-installed-p 'use-package)
(package-install 'use-package))
(use-package use-package-ensure-system-package
:ensure t)
(add-to-list 'load-path (expand-file-name "lisp" user-emacs-directory))
(add-to-list 'load-path (expand-file-name "org/lisp" "~/"))
Emacs comes with two input methods for Romanian: romanian-alt-prefix
and romanian-prefix
. However, I’m more accustomed to Romanian standard keyboard layout so I created a quail
package for it. This will be the default input method.
(require 'quail-romanian-standard)
(setq default-input-method 'romanian-standard)
(require 'rp-utils)
(setq-default custom-file (expand-file-name "custom.el" user-emacs-directory))
(when (file-exists-p custom-file)
(load custom-file t))
(setq inhibit-startup-message t)
(tool-bar-mode -1)
(scroll-bar-mode -1)
(fset 'yes-or-no-p 'y-or-n-p)
(global-set-key (kbd "<f5>") 'revert-buffer)
Found on a StackOverflow answer.
(global-visual-line-mode t)
From Emacs manual:
(delete-selection-mode 1)
From Reddit comment:
(setq save-interprogram-paste-before-kill t)
(setq initial-scratch-message "")
(setq dired-dwim-target t)
From Pragmatic Emacs.
(setq dired-listing-switches "-alh")
(setq sentence-end-double-space nil)
(setq display-time-day-and-date t
display-time-24hr-format t)
(display-time-mode 1)
(setq ring-bell-function 'ignore)
(add-hook 'before-save-hook 'delete-trailing-whitespace)
(global-unset-key (kbd "C-z"))
(setq calendar-week-start-day 1)
(unless (daemonp)
(setq confirm-kill-emacs 'y-or-n-p))
(defun rp/browse-url-firefox(url &rest ARGS)
"Browse URL using Firefox from Windows when running under WSL.
This function calls `shell-command' to pass
URL to the Firefox browser located at
`/mnt/c/Program\\ Files/Mozilla\\ Firefox/firefox.exe'.
The second argument ARGS is present to maintain compatibility."
(progn
(message "Browsing URL [%s] using external Firefox." url)
(shell-command
(concat "/mnt/c/Program\\ Files/Mozilla\\ Firefox/firefox.exe "
url))))
(when (rp/running-on-wsl)
(progn
(message "Running under WSL. The browse-url-browser-function will be overwritten.")
(setq browse-url-browser-function 'rp/browse-url-firefox)))
(setq bookmark-default-file "~/org/bookmarks"
eww-bookmarks-directory "~/org/")
(setq-default cursor-in-non-selected-windows nil)
(setq-default scroll-margin 2)
(set-default-coding-systems 'utf-8)
Taken from a reddit answer.
(setq backup-directory-alist
`((".*" . ,temporary-file-directory)))
(setq auto-save-file-name-transforms
`((".*" ,temporary-file-directory t)))
(add-to-list 'initial-frame-alist
'(fullscreen . maximized))
(use-package color-theme-sanityinc-tomorrow
:defer t)
(setq custom-safe-themes t)
Treating all custom themes as being safe seems to be risky. Ideally, I should be able to specify the list of custom themes like this:
(setq custom-safe-themes '("76ddb2e196c6ba8f380c23d169cf2c8f561fd2013ad54b987c516d3cabc00216" ;; sanityinc-tomorrow-day "04aa1c3ccaee1cc2b93b246c6fbcd597f7e6832a97aaeac7e5891e6863236f9f" ;; sanityinc-tomorrow-night "6fc9e40b4375d9d8d0d9521505849ab4d04220ed470db0b78b700230da0a86c1" ;; sanityinc-tomorrow-eighties default))
However, for some reason I can’t find right now, specifying the list of custom safe themes doesn’t work — when starting the daemon, I get a prompt whether to load and treat the theme as safe or not, which blocks the startup of the daemon.
(use-package circadian
:ensure t
:after smart-mode-line
:config
(if (and
(bound-and-true-p calendar-latitude)
(bound-and-true-p calendar-longitude))
(progn
(message "Latitude and longitude are set; themes will change according to sunset and sunrise.")
(setq circadian-themes '((:sunrise . sanityinc-tomorrow-day)
(:sunset . sanityinc-tomorrow-night))))
(progn
(message "Latitude and longitude not set; themes will change at 8:00 and 19:30.")
(setq circadian-themes '(("8:00" . sanityinc-tomorrow-day)
("19:30" . (sanityinc-tomorrow-night sanityinc-tomorrow-eighties))))))
(add-hook 'circadian-after-load-theme-hook
#'(lambda (theme)
(sml/apply-theme 'respectful)))
(circadian-setup))
As specified in the blog post of Mike Zamansky.
(defun rp/setup-ibuffer ()
(progn
(message "Setting-up Ibuffer.")
(ibuffer-auto-mode 1)
(ibuffer-switch-to-saved-filter-groups "default")))
(use-package ibuffer
:defer t
:config
(progn
(setq ibuffer-saved-filter-groups
(quote (("default"
("dired" (mode . dired-mode))
("org" (name . "^.*org$"))
("web" (or (mode . web-mode)
(mode . js2-mode)))
("shell" (or (mode . eshell-mode)
(mode . shell-mode)))
("programming" (or (mode . python-mode)
(mode . lisp-mode)
(mode . csharp-mode)
(mode . js2-mode)))
("doc-view" (mode . doc-view-mode))
("magit" (name . "^magit[:-].*"))
("latex" (or (mode . latex-mode)
(mode . bibtex-mode)))
("emacs" (or (name . "^\\*scratch\\*$")
(name . "^\\*Messages\\*$")))
("helm" (mode . helm-major-mode))
("powershell" (mode . powershell-mode))
("ledger" (mode . ledger-mode))
("pdf" (mode . pdf-view-mode))
("XML" (mode . nxml-mode))))))
;; Don't show filter groups if there are no buffers in that group
(setq ibuffer-show-empty-filter-groups nil))
:bind
(:map global-map
("C-x C-b" . ibuffer))
:hook
(ibuffer-mode . rp/setup-ibuffer))
(use-package expand-region
:defer t
:bind ("C-=" . er/expand-region))
For some reason smart-mode-line
needs to be loaded before circadian
to avoid a mess in the mode-line.
(use-package smart-mode-line
:hook
(after-init . smart-mode-line-enable)
:config
(setq sml/no-confirm-load-theme t)
(setq sml/theme 'respectful)
(sml/setup))
(use-package nyan-mode
:after smart-mode-line
:config
(nyan-mode 1))
From ace-window for easy window switching:
(use-package ace-window
:defer t
:bind
(:map global-map
("C-x o" . ace-window))
:config
(progn
(custom-set-faces
'(aw-leading-char-face
((t (:inherit ace-jump-face-foreground :height 3.0)))))))
(use-package undo-tree
:defer t
:defer t
:init
(progn
(setq undo-tree-history-directory-alist
`(("." . ,temporary-file-directory)))
(global-undo-tree-mode)))
(use-package which-key
:defer t
:config
(which-key-mode))
(use-package try
:defer t)
(when (version<= "25.3" emacs-version)
(use-package beginend
:defer t
:hook
(after-init . beginend-global-mode)))
Atomic chrome allows editing text from a text area within browser using Emacs. Since I use Firefox I GhostText extension needs to be installed in Firefox in order for this to work.
(use-package atomic-chrome
:defer t
:when (display-graphic-p)
:config
(progn
(setq atomic-chrome-buffer-open-style 'frame
atomic-chrome-url-major-mode-alist '(("github\\.com" . gfm-mode)
("reddit\\.com" . markdown-mode)))
(atomic-chrome-start-server)))
A merge of configuration from Sacha Chua and other various sources.
(use-package helm
:defer t
:diminish helm-mode
:init
(progn
(setq helm-candidate-number-limit 100)
;; From https://gist.github.com/antifuchs/9238468
(setq helm-idle-delay 0.0 ; update fast sources immediately (doesn't).
helm-input-idle-delay 0.01 ; this actually updates things relatively quickly.
helm-yas-display-key-on-candidate t
helm-quick-update t
helm-M-x-requires-pattern nil
helm-ff-skip-boring-files t)
;; Configuration from https://gist.github.com/m3adi3c/66be1c484d2443ff835b0c795d121ee4#org3ac3590
(setq helm-split-window-in-side-p t ; open helm buffer inside current window, not occupy whole other window
helm-move-to-line-cycle-in-source t ; move to end or beginning of source when reaching top or bottom of source.
helm-ff-search-library-in-sexp t ; search for library in `require' and `declare-function' sexp.
helm-scroll-amount 8) ; scroll 8 lines other window using M-<next>/M-<prior>
)
:hook (after-init . helm-mode)
:bind (:map global-map
("C-c h" . helm-mini)
("C-h a" . helm-apropos)
("C-x b" . helm-buffers-list)
("M-y" . helm-show-kill-ring)
("M-x" . helm-M-x)
("C-x c o" . helm-occur)
("C-x c y" . helm-yas-complete)
("C-x c Y" . helm-yas-create-snippet-on-region)
("C-x c SPC" . helm-all-mark-rings)
("C-x C-f" . helm-find-files)
:map helm-map
("TAB" . helm-execute-persistent-action)))
Bindings from Sacha Chua.
(use-package helm-swoop
:defer t
:after helm
:bind
(("C-S-s" . helm-swoop)
("M-i" . helm-swoop)
("M-s s" . helm-swoop)
("M-s M-s" . helm-swoop)
("M-I" . helm-swoop-back-to-last-point)
("C-c M-i" . helm-multi-swoop)
("C-c M-I" . helm-multi-swoop-all)))
(use-package helm-xref
:defer t
:after helm)
Define a function to change the spelcheck dictionary to English, and enable the flyspell-mode
in order to avoid spelling mistakes in commits.
(defun rp/git-commit-setup()
"Setup the git commit buffer."
(progn
(ispell-change-dictionary "en_US")
(flyspell-mode 1)))
(use-package magit
:defer t
:bind (("C-x g" . magit-status))
:hook (git-commit-setup . rp/git-commit-setup))
(use-package forge
:defer t
:after magit)
For some reason, forge
is unable to generate the token when running under Cygwin. To avoid this issue, just create a Personal Access Token
in GitHub settings page and store it in the ~/.authinfo
file like this:
machine api.github.com login <username>^forge password <personal token>
As found in Git Gutter in Emacs | Ian Y.E. Pan:
(use-package git-gutter
:hook (prog-mode . git-gutter-mode)
:config
(setq git-gutter:update-interval 0.02))
From Emacs configuration of angrybacon.
(use-package company
:defer t
:config
(setq-default
company-idle-delay .2
company-minimum-prefix-length 1
company-require-match nil
company-tooltip-align-annotations t
company-show-numbers t
company-show-quick-access t)
:hook
(after-init . global-company-mode))
(use-package company-quickhelp
:defer t
:after company
:bind
(:map company-active-map
("C-c h" . company-quickhelp-manual-begin))
:init (with-eval-after-load 'company
(company-quickhelp-mode)))
As specified in the documentation.
(use-package markdown-mode
:defer t
:commands (markdown-mode gfm-mode)
:mode (("README\\.md\\'" . gfm-mode)
("\\.md\\'" . markdown-mode)
("LICENSE" . markdown-mode)
("\\.markdown\\'" . markdown-mode))
:init
(setq markdown-command "multimarkdown"))
(use-package gh-md
:defer t)
(defun rp/setup-csv-mode()
(progn
(display-line-numbers-mode)
(hl-line-mode)))
(use-package csv-mode
:defer t
:config
(rp/setup-csv-mode))
(use-package yasnippet
:defer t
:hook
(after-init . yas-global-mode))
(use-package yasnippet-snippets
:defer t
:after yasnippet)
(defun rp/try-activate-virtual-environment()
"Try to activate the virtual environment.
The virtual environment is assumed to be located
in directory .venv under projectile root directory."
(let* ((project-dir (projectile-project-root))
(venv-dir (concat project-dir ".venv")))
(if (file-directory-p venv-dir)
(progn
(message (format "Activating virtual environment from %s." venv-dir))
(pyvenv-activate venv-dir)))))
When on Cygwin
use native
indexing for projectile
as mentioned in this Quora answer. It’s slower but it does the job.
(use-package projectile
:defer t
:bind-keymap
("C-c p" . projectile-command-map)
:config
(progn
(when (eq system-type 'cygwin)
(setq projectile-indexing-method 'native)))
:hook
((magit-mode . projectile-mode)
(projectile-mode . rp/try-activate-virtual-environment)))
(use-package helm-projectile
:defer t
:hook
(projectile-mode . helm-projectile-on)
:config
(setq projectile-completion-system 'helm))
(use-package eldoc
:defer t
:hook ((emacs-lisp-mode . eldoc-mode)
(eval-expression-minibuffer-setup . eldoc-mode)
(lisp-mode-interactive-mode . eldoc-mode)
(python-mode . eldoc-mode)
(eshell-mode . eldoc-mode)
(org-mode . eldoc-mode)))
(use-package graphviz-dot-mode
:defer t)
The examle of using use-package
for configuring pdf-tools
can be found here.
(use-package pdf-tools
:defer t
:config
(pdf-tools-install)
(setq-default pdf-view-display-size 'fit-page)
:mode (("\\.pdf" . pdf-view-mode)))
Requires ledger
to be installed:
sudo apt-get install ledger
(defun rp/clean-ledger-buffer()
(when (equal major-mode 'ledger-mode)
(ledger-mode-clean-buffer)))
(use-package ledger-mode
:defer t
:config
(progn
(setq ledger-reconcile-default-commodity "RON")
(setq ledger-schedule-file "~/org/financial/ledger-schedule.ledger")
(add-hook 'before-save-hook 'rp/clean-ledger-buffer)))
(use-package flycheck-ledger
:defer t
:hook (ledger-mode . flycheck-mode))
(use-package newst-treeview
:defer t
:init
(require 'rp-feeds-urls)
(setq newsticker-dir "~/org/newsticker/"
newsticker-frontend 'newsticker-treeview
newsticker-cache-filename "~/org/newsticker/.newsticker-cache"
newsticker-retrieval-interval -1
newsticker-download-logos nil
newsticker-treeview-treewindow-width 60
newsticker-url-list rp/newsticker-feeds)
:config
(add-hook 'kill-emacs-hook (lambda ()
(if (fboundp 'newsticker-treeview-quit)
(newsticker-treeview-quit)))))