You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

637 lines
20 KiB
EmacsLisp

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

;; -*- lexical-binding: t; -*-
(add-to-list 'custom-theme-load-path "~/.workspace/elisp-themes/")
(let ((home (getenv "HOME")))
;; Added by Package.el. This must come before configurations of
;; installed packages. Don't delete this line. If you don't want it,
;; just comment it out by adding a semicolon to the start of the line.
;; You may delete these explanatory comments.
(package-initialize)
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))
;;(add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/") t)
(add-to-list 'package-archives '("gnu" . "https://elpa.gnu.org/packages/"))
;; Where custom config values should be saved
(setq custom-file (concat home "/.custom.el"))
(load custom-file))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;; GLOBAL MODES ;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(require 'flyspell)
(add-hook 'prog-mode-hook 'flyspell-prog-mode)
(add-hook 'prog-mode-hook 'linum-mode)
(add-hook 'prog-mode-hook 'show-paren-mode)
(add-hook 'prog-mode-hook 'display-fill-column-indicator-mode)
(defun hugot-delete-trailing-whitespace-hook ()
"Add buffer-local book to delete trailing white space."
(make-variable-buffer-local 'before-save-hook)
(add-hook 'before-save-hook 'delete-trailing-whitespace))
(add-hook 'prog-mode-hook 'hugot-delete-trailing-whitespace-hook)
(add-hook 'yaml-mode 'hugot-delete-trailing-whitespace-hook)
(yas-global-mode)
;; Switch between tabs with C-number
(setq-default tab-bar-select-tab-modifiers '(control))
;; Add a tab bar up top
(tab-bar-mode)
;; enable flycheck everywhere
(global-flycheck-mode)
;; Save minibuffer history between sessions
(savehist-mode 1)
;; Show the current time in the modeline
(display-time-mode 1)
(add-hook 'prog-mode-hook 'abbrev-mode)
;; minimal gui
(when (eq window-system "x")
(require 'emojify)
(global-emojify-mode 1)
(scroll-bar-mode -1))
(tool-bar-mode -1)
(add-hook 'after-init-hook 'global-company-mode)
(xclip-mode 1)
(setq-default fill-column 80)
(setq mouse-wheel-progressive-speed nil) ;; don't accelerate scrolling
(setq epa-pinentry-mode 'loopback)
;; Disable GUI prompt for GPG
(defadvice epg--start (around advice-epg-disable-agent activate)
(let ((agent (getenv "GPG_AGENT_INFO")))
(setenv "GPG_AGENT_INFO" nil)
ad-do-it
(setenv "GPG_AGENT_INFO" agent)))
;; Disable all colours when rendering HTML using shr by replacing its
;; colourize function with a stub.
(advice-add 'shr-colorize-region :around (defun shr-no-colourize-region (&rest ignore)))
;; Let's make sure that lanuage settings are not dependent on the
;; environment
;;(set-language-environment "English")
(setq system-time-locale "en_US.UTF-8")
(setq calendar-week-start-day 1
calendar-day-name-array
["Sunday" "Monday" "Tuesday" "Wednesday"
"Thursday" "Friday" "Saturday"]
calendar-month-name-array
["January" "February" "March" "April" "May"
"June" "Juli" "August" "Septembre"
"October" "November" "December"])
;; Don't ask wether to save abbrevs
(setq save-abbrevs 'silent)
;; ;;Don't auto-save files in the same directory as the file itself
;; (setq auto-save-file-name-transforms
;; `((".*" "~/.emacs-saves/" t)))
(setq show-paren-delay 0)
(fset 'yes-or-no-p 'y-or-n-p)
(setq inhibit-startup-message t inhibit-startup-echo-area-message t)
(setq-default indent-tabs-mode nil)
(setq-default tab-width 4)
(setq-default tab-bar-tab-hints t)
;; This is very php-specific, it would be nice if this could be
;; modularized more per filetype
(setq grep-find-ignored-directories
'(".cache" "vendor" ".git" ".idea" "vendor" "var"
"web" "node_modules" "httpconf"))
;; Disable request to save open files (because it is annoying)
(setq grep-save-buffers nil)
;; Disable annoying sounds
(setq ring-bell-function 'ignore)
;; Always follow symlinks
(setq vc-follow-symlinks t)
(setq auth-sources '("~/.authinfo.gpg"))
(put 'erase-buffer 'disabled nil)
(setq flycheck-emacs-lisp-load-path 'inherit)
(add-to-list 'load-path "~/projects/phpinspect.el")
(add-to-list 'load-path "~/projects/qtoot")
(when (require 'qtoot nil 'noerror)
(setq qtoot-enable-drafts t))
;; END GLOBAL MODES
;;;;;;;;;;;;;;;;;;;;;
;;;;; POWERLINE ;;;;;
;;;;;;;;;;;;;;;;;;;;;
(powerline-default-theme)
(setq powerline-display-buffer-size nil)
(setq display-time-default-load-average nil)
;; END POWERLINE
;;;;;;;;;;;;;;;;;;;;
;;;;; WEB MODE ;;;;;
;;;;;;;;;;;;;;;;;;;;
(add-to-list 'auto-mode-alist '("\\.yml\\'" . yaml-mode))
(add-to-list 'auto-mode-alist '("\\.yaml\\'" . yaml-mode))
;; When web-mode should be active
(add-to-list 'auto-mode-alist '("\\.cshtml" . web-mode))
(add-to-list 'auto-mode-alist '("\\.twig" . web-mode))
(add-to-list 'auto-mode-alist '("\\.svelte" . web-mode))
(add-to-list 'auto-mode-alist '("\\.java" . java-mode))
;; END WEB MODE
;;;;;;;;;;;;;;;;
;;;;; JAVA ;;;;;
;;;;;;;;;;;;;;;;
(when (require 'lsp-java nil t)
(setq lsp-java-import-gradle-version "7.4.2")
(setq lsp-java-import-gradle-wrapper-enabled nil))
(add-hook 'java-mode-hook 'lsp)
(defun hugot-java-indent-setup ()
(setq c-default-style "java")
(c-set-offset 'arglist-intro '+)
(c-set-offset 'arglist-close '0)
(c-set-offset 'case-label '+))
(add-hook 'java-mode-hook 'hugot-java-indent-setup)
;; END JAVA
;;;;;;;;;;;;;;;;;;;;;;
;;;;; JAVASCRIPT ;;;;;
;;;;;;;;;;;;;;;;;;;;;;
(require 'flycheck)
(add-to-list 'auto-mode-alist '("\\.jsx?$" . web-mode))
(setq web-mode-content-types-alist '(("jsx" . "\\.js[x]?\\'")))
(add-to-list 'flycheck-disabled-checkers 'javascript-jshint)
(add-to-list 'flycheck-disabled-checkers 'json-jsonlist)
(flycheck-add-mode 'javascript-eslint 'web-mode)
(defun hugot-javascript-web-mode-hook ()
(when (or (string-match "\\.svelte$" (buffer-name)) (string-match "\\.js$" (buffer-name)))
(setq tab-width 2)
(setq web-mode-markup-indent-offset 2)
(setq web-mode-code-indent-offset 2)
(setq js2-basic-offset 2)
(setq web-mode-script-padding 2)
(setq web-mode-script-padding 2)
(setq web-mode-block-padding 2)))
(add-hook 'web-mode-hook 'hugot-javascript-web-mode-hook)
;; END JAVASCRIPT
;;;;;;;;;;;;;;;
;;;;; PHP ;;;;;
;;;;;;;;;;;;;;;
(defvar hugot-php-mode-expand-list nil "PHP mode expansions.")
(setq hugot-php-mode-expand-list
'(("pun" "public function (): \n{\n\n}\n" (17 18 21 24))
("prn" "private function (): \n{\n\n}\n" (18 19 22 25))
("fn" "function ():\n{\n\n}" (10 11 15))
("pr" "private " ())
("pu" "public " ())))
(add-to-list 'auto-mode-alist `("\\.php$" . php-mode))
(defun hugot-php-personal-hook ()
(require 'expand)
(expand-add-abbrevs php-mode-abbrev-table hugot-php-mode-expand-list)
(abbrev-mode 1)
(set (make-local-variable 'company-minimum-prefix-length) 0)
(set (make-local-variable 'company-tooltip-align-annotations) t)
(set (make-local-variable 'company-idle-delay) 0.1)
(set (make-local-variable 'company-backends) '(phpinspect-company-backend))
;; Handy namespace stuff
(define-key php-mode-map (kbd "C-c u") 'phpinspect-fix-uses-interactive)
(define-key php-mode-map (kbd "C-c t t") 'phptest-run-test-for-current-buffer)
(define-key php-mode-map (kbd "C-c t p") 'phptest-run-tests-for-current-buffer-project)
(define-key php-mode-map (kbd "C-c t o") 'phptest-open-test-for-current-buffer)
(phpinspect-mode))
(when (require 'phpinspect nil t)
(add-hook 'php-mode-hook #'hugot-php-personal-hook))
;; END PHP
;;;;;;;;;;;;;;;
;;;;; CSS ;;;;;
;;;;;;;;;;;;;;;
(defun hugot-css-mode-hook ()
"Custom actions to execute when initializing css-mode"
(setq-local company-minimum-prefix-length 1)
(setq-local company-idle-delay 0))
(add-hook 'css-mode-hook 'hugot-css-mode-hook)
;; END CSS
;;;;;;;;;;;;;;;;;;;;;;;;
;;;;; COMPANY MODE ;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;
(with-eval-after-load 'company
(dolist (map (list company-active-map company-search-map))
(define-key map (kbd "C-n") nil)
(define-key map (kbd "C-p") nil)
(define-key map (kbd "M-n") #'company-select-next)
(define-key map (kbd "M-p") #'company-select-previous))
(setq company-auto-complete t)
(setq company-idle-delay 1)
(setq company-auto-complete 'company-explicit-action-p)
(global-set-key (kbd "M-p") 'company-select-previous)
(global-set-key (kbd "M-n") 'company-select-next)
(add-to-list 'company-backends 'company-shell t)
(add-to-list 'company-backends 'company-dabbrev-code t)
(add-to-list 'company-backends 'company-capf))
(defun hugot-make-capf-dominant-company-backend ()
(interactive)
(setq company-backends
`(company-capf
,@(seq-filter (lambda (elt)
(not (eq 'company-capf elt)))
company-backends))))
;; END COMPANY MODE
;;;;;;;;;;;;;;
;;;;; GO ;;;;;
;;;;;;;;;;;;;;
(require 'go-mode)
(require 'company-go)
(require 'go-eldoc)
(require 'flycheck)
(defvar hugot-go-mode-expand-list
'(("ern" "if err != nil {\n\n}\n" (17))
("die" "log.Fatal()" (11))
("ernd" "if err!= nil {\nlog.Fatal(err)\n}\n" ())
("fn" "func () {\n}\n" (6))
("prnl" "fmt.Prinln()" (12))
("prnf" "fmt.Printf()" (12))
("sprn" "fmt.Sprintf()" (13)))
"Alist with golang expand snippets for use with ABBREV-MODE.")
;;;###autoload
(defun hugot-go-mode-hook ()
"Personal go-mode hook."
(require 'lsp-mode)
(require 'lsp-ui)
(require 'expand)
(expand-add-abbrevs go-mode-abbrev-table hugot-go-mode-expand-list)
(abbrev-mode 1)
(lsp)
(lsp-deferred)
(lsp-ui-mode)
(lsp-ui-sideline-mode)
(add-hook 'before-save-hook 'gofmt-before-save) ; gofmt before every save
(flymake-mode 1)
(local-set-key (kbd "M-.") 'godef-jump) ; Godef jump key binding
(local-set-key (kbd "M-*") 'pop-tag-mark)
(local-set-key (kbd "M-p") 'compile) ; Invoke compiler
(local-set-key (kbd "M-P") 'recompile) ; Redo most recent compile cmd
(local-set-key (kbd "M-]") 'next-error) ; Go to next error (or msg)
(local-set-key (kbd "M-[") 'previous-error) ; Go to previous error or msg
(local-set-key (kbd "C-c g") 'hugot-go-run)
(setq gofmt-command "goimports")
(hugot-make-capf-dominant-company-backend))
(add-hook 'go-mode-hook 'hugot-go-mode-hook)
(defun hugot-go-run ()
(interactive)
(let ((project-dir (lsp--suggest-project-root))
(start-buffer (current-buffer)))
(with-current-buffer (get-buffer-create "GO-RUN")
(display-buffer (current-buffer))
(let ((default-directory project-dir))
(make-process
:name "GO-RUN OUTPUT"
:command `("go" "run" "main.go")
:buffer (current-buffer)
:stderr (current-buffer))))))
;; END GO
;;;;;;;;;;;;;;;;;;;
;;;;; SH MODE ;;;;;
;;;;;;;;;;;;;;;;;;;
(declare-function 'sh-electric-here-document-mode "sh-script")
;; Disable automatic expansion of << to <<EOF
(add-hook 'sh-mode-hook
(lambda ()
(sh-electric-here-document-mode -1)))
;; END SH MODE
;;;;;;;;;;;;;;;
;;;;; SQL ;;;;;
;;;;;;;;;;;;;;;
(add-hook 'sql-mode-hook 'sqlind-minor-mode)
;; END SQL
;;;;;;;;;;;;;;;;;;
;;;;; SVELTE ;;;;;
;;;;;;;;;;;;;;;;;;
(defun svelte-mode-sgml-empty-tag-p-advice (old-function tag-name)
"Advice function intended to wrap around `sgml-empty-tag-p
Makes case significant when checking whether tags need to be
closed or not, to not confuse elements with Svelte components."
(if (eq major-mode 'svelte-mode)
(assoc-string tag-name sgml-empty-tags)
(funcall old-function tag-name)))
(defun svelte-mode-sgml-unclosed-tag-p-advice (old-function tag-name)
"Advice function intended to wrap around `sgml-unclosed-tag-p
Makes case significant when checking whether tags need to be
closed or not, to not confuse elements with Svelte components."
(if (eq major-mode 'svelte-mode)
(assoc-string tag-name sgml-unclosed-tags)
(funcall old-function tag-name)))
(advice-add 'sgml-empty-tag-p :around 'svelte-mode-sgml-empty-tag-p-advice)
(advice-add 'sgml-unclosed-tag-p :around 'svelte-mode-sgml-unclosed-tag-p-advice)
;; END SVELTE
;;;;;;;;;;;;;;;;;;;;
;;;;; KEYBINDS ;;;;;
;;;;;;;;;;;;;;;;;;;;
(global-unset-key (kbd "C-x C-c"))
(global-set-key (kbd "C-x C-c C-x C-c") 'save-buffers-kill-terminal)
;; Unbind `dired'. Not necessary anyways since there is {C-x C-d} to run
;; `ido-list-directory' if I ever really want to use dired. Also there is {C-c
;; C-x C-d} to open `dired-sidebar'.
(global-unset-key (kbd "C-x d"))
(global-set-key (kbd "C-x d d") 'deft)
(global-set-key (kbd "C-x d f") 'deft-new-file-named)
(global-set-key (kbd "C-c e") 'emojify-insert-emoji)
(global-set-key (kbd "C-x g") 'magit-status)
(global-set-key (kbd "C-x O") (lambda () (interactive) (other-window -1)))
;; TOOD: This keymap is only usefull for PHP projects, Maybe think of
;; a way to only enable it for files that are in PHP projects?
(global-set-key (kbd "C-c a") 'phpinspect-find-class-file)
(global-set-key (kbd "C-c c") 'phpinspect-find-own-class-file)
;; EVIL EVIL
(global-set-key (kbd "C-x 5 0")
(lambda ()
(interactive)
(message "That is probably not what you meant!")))
(global-set-key (kbd "C-c f") 'project-find-file)
(global-set-key (kbd "C-c b") 'hugot-project-switch-to-buffer)
;; Switch between tabs with C-number
(setq tab-bar-select-tab-modifiers '(control))
;; END KEYBINDS
;;;;;;;;;;;;;;;;
;;;;; DEFT ;;;;;
;;;;;;;;;;;;;;;;
(require 'deft)
(defun hugot-deft-window-width (old-function)
(- (funcall old-function) 1))
(advice-add 'deft-current-window-width :around #'hugot-deft-window-width)
(eval-after-load "deft"
(progn
(setq deft-directory "~/projects/deft")
(custom-set-variables '(deft-extensions '("kotl" "txt" "text" "md" "markdown" "org")))
(setq-default deft-default-extension "kotl")
(setq deft-use-filename-as-title t)
(setq deft-strip-summary-regexp "^\\(\n\\|;;\\|\"\\|[[:digit:]]\\|[[:blank:]]*\\[\\|[a-z]\\|\\|[[:blank:]]+(creator\\|.*\\]$\\).*\\|\\|[\n \t]+")))
;; END DEFT
;;;;;;;;;;;;;;;;;;;;
;;;;; EWW MODE ;;;;;
;;;;;;;;;;;;;;;;;;;;
(defun hugot-eww-title (old-function)
"Intended to be added as advice around `eww-update-header-line-format'.
OLD-FUNCTION must be the function that is being adviced."
(rename-buffer (concat
"[eww] "
(or (plist-get eww-data :title)
"<untitled>"))
t)
(funcall old-function))
(advice-add #'eww-update-header-line-format :around #'hugot-eww-title)
;; END EWW MODE
;;;;;;;;;;;;;;;
;;;;; IDO ;;;;;
;;;;;;;;;;;;;;;
(require 'ido)
(setq ido-enable-flex-matching t)
(ido-everywhere 1)
;;(ido-vertical-mode 1)
;;; This is from ido-completing-read+ which made function/command completion garbage slow.
;;(ido-ubiquitous-mode 1)
(ido-mode 1)
(defun hugot-completing-read (prompt coll pred &rest args)
"`completing-read-default' wrapper to use as `completing-read-function'.
Enables ido for M-x and describe-function/describe-variable."
(let ((cr-args `(,prompt ,coll ,pred ,@args))
(cr-function #'completing-read-default))
;; When the collection is a list, ido knows what to do with it
(cond ((and (listp coll) (stringp (car coll)))
(setq cr-function #'ido-completing-read))
((and (listp coll) (consp (car coll)))
(setq cr-function #'ido-completing-read)
(setq coll (mapcar 'car coll))
(setq cr-args `(,prompt ,coll ,pred ,@args)))
;; Collection is a function, ido can't deal with those, so for some cases we
;; force the function to return all matches that contain "empty string", which
;; (usually) results in them returning every possible value.
((functionp coll)
;; Used for `describe-function'
(if (or (eq #'help--symbol-completion-table coll)
;; Should match the prompt of `project-find-file'
(string-match "^Find file in" prompt))
(setq cr-function #'ido-completing-read
cr-args `(,prompt ,(funcall coll "" pred t) ,pred ,@args))
(pcase pred
;; Used for M-x (`read-extended-command')
('commandp
(setq cr-function #'ido-completing-read
cr-args `(,prompt ,(funcall coll "" pred t) ,pred ,@args)))))))
(apply cr-function cr-args)))
(setq completing-read-function #'hugot-completing-read)
;; Use IDO for M-x
;;(smex-initialize)
;; (global-set-key (kbd "M-x") 'smex)
;; (global-set-key (kbd "M-X") 'smex-major-mode-commands)
;; This is your old M-x.
(global-set-key (kbd "C-c C-c M-x") 'execute-extended-command)
(defvar hugot-kr-cr-corpse-length 20)
(defun hugot-kr-cr ()
"Completing read for the `kill-ring'.
Returns the kill-ring index of the selected item, for use as
argument to `yank' and the like."
(interactive)
(let* ((body-count 0)
(alist (mapcar (lambda (corpse)
(cons
(replace-regexp-in-string
"[[:blank:]]+"
" "
(truncate-string-to-width corpse
hugot-kr-cr-corpse-length))
(setq body-count (+ body-count 1))))
kill-ring-yank-pointer))
(corpse (completing-read "Kill ring: " alist)))
(alist-get corpse alist 0 nil #'string=)))
(defun hugot-kr-cr-yank (&optional arg)
"Yank from the kill-ring, seleting which string to yank using `completing-read'.
See `yank' for documentation of ARG."
(interactive (list (hugot-kr-cr)))
(let ((yank-function #'yank)
;; The yank pointer should stay the same, but there's no way to pass DO-NOT-MOVE
;; to `current-kill' when calling the yank function, so it's stored here to
;; recover it's state after yanking. The yank function appropriate for the current
;; mode needs to be called in stead of just using `insert', because using `insert'
;; in kotl-mode (for example) breaks it.
(stored-yank-pointer (cl-copy-list kill-ring-yank-pointer)))
(cond ((eq major-mode 'kotl-mode)
(setq yank-function #'kotl-mode:yank)))
(funcall yank-function arg)
;; Restore yank-pointer
(setq kill-ring-yank-pointer stored-yank-pointer)))
;; END IDO
(require 'hyperbole)
(eval-after-load 'kotl-mode '(require 'hugot-kotl-mode))
;; Emoji support
(set-fontset-font t 'symbol "Apple Color Emoji")
(set-fontset-font t 'symbol "Noto Color Emoji" nil 'append)
(set-fontset-font t 'symbol "Segoe UI Emoji" nil 'append)
(set-fontset-font t 'symbol "Symbola" nil 'append)
(setq server-socket-dir (concat (getenv "HOME") "/.cache/emacs"))
(defun hugot-set-appearance ()
"Set appearance settings."
(interactive)
(load-theme 'epaper)
(enable-theme 'epaper)
(fringe-mode (alist-get "right-only" fringe-styles nil nil 'string=))
(window-divider-mode)
(scroll-bar-mode -1)
(menu-bar-mode -1)
(set-frame-font "Hack 11" nil t)
(set-face-attribute 'default nil :height 110)
(setq linum-format "%d "))
(hugot-set-appearance)
(put 'downcase-region 'disabled nil)
;;;;;;;;;;;;;;;;;;;;
;;;;; COMMANDS ;;;;;
;;;;;;;;;;;;;;;;;;;;
(defun insert-date ()
(interactive)
(insert (format-time-string "%Y-%m-%d %H:%M")))
(defun hugot-list-project-buffers ()
(let ((project-dir (cdr (project-current)))
(buffers))
(dolist (buffer (buffer-list))
(when (and (buffer-file-name buffer)
(file-in-directory-p (buffer-file-name buffer)
project-dir)
(push buffer buffers))))
buffers))
(defun hugot-project-switch-to-buffer (buffer)
(interactive (list (completing-read
"Buffer: "
(mapcar #'buffer-name
(hugot-list-project-buffers)))))
(switch-to-buffer buffer))
(defun hugot-cp-rsa ()
(interactive)
(with-temp-buffer
(insert-file-contents-literally "~/.ssh/id_rsa.pub")
(copy-region-as-kill (point-min) (point-max))
(message "~/.ssh/id_rsa.pub contents added to kill-ring")))
;; END COMMANDS