;;; init.el --- spacemacs like config ;; foosinn ;;; Commentary: ;; my config ;;; Code: ;; sane defaults (setq delete-old-versions -1 ) ; delete excess backup versions silently (setq version-control t ) ; use version control (setq vc-make-backup-files t ) ; make backups file even when in version controlled dir (setq backup-directory-alist `(("." . "~/.emacs.d/backups")) ) ; which directory to put backups file (setq vc-follow-symlinks t ) ; don't ask for confirmation when opening symlinked file (setq auto-save-file-name-transforms '((".*" "~/.emacs.d/auto-save-list/" t)) ) ;transform backups file name (setq inhibit-startup-screen t ) ; inhibit useless and old-school startup screen (setq ring-bell-function 'ignore ) ; silent bell when you make a mistake (setq coding-system-for-read 'utf-8 ) ; use utf-8 by default (setq coding-system-for-write 'utf-8 ) (setq sentence-end-double-space nil) ; sentence SHOULD end with only a point. (setq initial-scratch-message "Welcome in Emacs") ; print a default message in the empty scratch buffer opened at startup (setq focus-follows-mouse nil) ; stop popups from getting focus (setq mouse-autoselect-window nil) ; stop popups from getting focus (setq display-line-numbers 'relative) ; show relative line-numers ;; global keybindings (global-set-key (kbd "C-k") 'previous-line) (global-set-key (kbd "C-j") 'next-line) ;; package manager (require 'package) (setq package-enable-at-startup nil) ; tells emacs not to load any packages before starting up (setq package-archives '(("org" . "http://orgmode.org/elpa/") ("gnu" . "http://elpa.gnu.org/packages/") ("melpa" . "https://melpa.org/packages/"))) (package-initialize) ;; use package (unless (package-installed-p 'use-package) (package-refresh-contents) (package-install 'use-package)) (require 'use-package) ;; themes (use-package doom-themes :ensure t) (use-package monokai-theme :ensure t :config (load-theme 'doom-monokai-pro t)) (use-package all-the-icons :ensure t) (use-package doom-modeline :ensure t :hook (after-init . doom-modeline-mode)) (set-face-attribute 'default nil :family "Meslo LG S DZ" :height 105 :weight 'normal :width 'normal) ;; evil config (use-package evil :ensure t :config (evil-mode 1) (global-display-line-numbers-mode)) (use-package evil-surround :ensure t :config (global-evil-surround-mode 1) (evil-define-key 'visual evil-surround-mode-map "s" 'evil-surround-region)) (use-package evil-matchit :ensure t :config (global-evil-matchit-mode 1)) ;; ivy config (use-package ivy :ensure t :config (ivy-mode) (setq ivy-height 10) (setq ivy-use-virtual-buffers t) (setq enable-recursive-minibuffers t) (setq ivy-re-builders-alist '((swiper . ivy--regex-plus) (t . ivy--regex-plus))) (define-key ivy-minibuffer-map (kbd "C-j") 'ivy-next-line) (define-key ivy-minibuffer-map (kbd "C-k") 'ivy-previous-line) (define-key ivy-minibuffer-map (kbd "C-h") (kbd "DEL")) (define-key ivy-minibuffer-map (kbd "C-S-h") help-map) (define-key ivy-minibuffer-map (kbd "C-l") 'ivy-alt-done) (define-key ivy-minibuffer-map (kbd "") 'minibuffer-keyboard-quit)) (use-package ivy-xref :ensure t :init (setq xref-show-xrefs-function #'ivy-xref-show-xrefs)) (use-package ivy-rich :ensure t :config (ivy-rich-mode 1)) ;; counsel (use-package counsel :ensure t :config (counsel-mode 1)) (use-package counsel-projectile :ensure t) (use-package swiper :ensure t) ;; projectile (use-package projectile :ensure t :config (projectile-mode +1)) ;; which key (use-package which-key :ensure t :config (which-key-mode) (which-key-setup-side-window-bottom) (which-key-setup-minibuffer) (setq which-key-idle-delay .3) ) ;; langs ;; ;; vue (use-package vue-mode :ensure t :config (add-to-list 'auto-mode-alist '("\\.vue\\'" . vue-mode))) ;; js (use-package js2-mode :ensure t :config (add-to-list 'auto-mode-alist '("\\.js\\'" . js2-mode))) ;; golang (use-package go-mode :ensure t :config (add-to-list 'auto-mode-alist '("\\.go\\'" . go-mode)) ) ;; yaml (use-package yaml-mode :ensure t :config (add-to-list 'auto-mode-alist '("\\.yaml\\'" . yaml-mode)) (add-to-list 'auto-mode-alist '("\\.yml\\'" . yaml-mode)) ) ;; dockerfile (use-package dockerfile-mode :ensure t :config (add-to-list 'auto-mode-alist '("Dockerfile\\'" . dockerfile-mode))) ;; puppet (use-package puppet-mode :ensure t :config (add-to-list 'auto-mode-alist '("\\.pp\\'" . puppet-mode)) (general-define-key :states '(normal visual insert emacs) :keymaps 'puppet-mode-map :prefix "SPC" :non-normal-prefix "C-SPC" "ma" 'puppet-align-block ) ) ;; php (use-package php-mode :ensure t) ;; k8s (use-package k8s-mode :ensure t) ;; hcl (use-package hcl-mode :ensure t) ;; rust (use-package rust-mode :ensure t :config (setq rust-format-on-save t) (add-hook 'rust-mode-hook (lambda () (setq indent-tabs-mode nil))) ) (add-hook 'rust-mode-hook (lambda () (setq indent-tabs-mode nil))) ;; bazel / starlak (use-package bazel-mode :ensure t) ;; code-with-fun (global-undo-tree-mode) (evil-set-undo-system 'undo-tree) (use-package org-jira :ensure t :config (setq jiralib-url "https://coordinatr.thomann.de")) (use-package evil-org :ensure t :after org :hook (org-mode . (lambda () evil-org-mode))) (use-package org-roam :ensure t :init (setq org-roam-v2-ack t) :custom (org-roam-directory (file-truename "~/Sync/RoamNotes")) :config (org-roam-db-autosync-mode)) (use-package direnv :ensure t :config (direnv-mode)) (use-package rainbow-mode :ensure t :config (rainbow-mode)) (use-package hl-todo :ensure t :config (hl-todo-mode)) (use-package whitespace :config (setq whitespace-style '(face empty tabs lines-tail trailing)) (global-whitespace-mode t)) (use-package company :config (global-company-mode 1) (define-key company-active-map (kbd "C-n") 'company-select-next) (define-key company-active-map (kbd "C-p") 'company-select-previous) (define-key company-active-map (kbd "C-j") 'company-select-next) (define-key company-active-map (kbd "C-k") 'company-select-previous) (define-key company-search-map (kbd "C-n") 'company-select-next) (define-key company-search-map (kbd "C-p") 'company-select-previous) (define-key company-search-map (kbd "C-j") 'company-select-next) (define-key company-search-map (kbd "C-k") 'company-select-previous) (setq company-idle-delay 0.1 company-minimum-prefix-length 2 company-require-match nil)) (use-package company-box :hook (company-mode . company-box-mode)) (use-package highlight-indentation :ensure t) ;; lsp (use-package lsp-mode :ensure t :commands (lsp lsp-deferred) :hook (c++-mode . lsp-deferred) (dockerfile-mode . lsp-deferred) (go-mode . lsp-deferred) (javascript-mode . lsp-deferred) (js2-mode . lsp-deferred) (php-mode . lsp-deferred) (puppet-mode . lsp-deferred) (python-mode . lsp-deferred) (ruby-mode . lsp-deferred) (rust-mode . lsp-deferred) (vue-mode . lsp-deferred) :config (lsp-register-client (make-lsp-client :new-connection (lsp-stdio-connection '("bundle" "exec" "--keep-file-descriptors" "/nix/store/pgjhgk5d41q6jjxiympqjs3qzxf52mg9-puppet-editor-services-9fd4984/puppet-languageserver" "--local-workspace=/home/stefan/git/sysadmin/puppet" "--debug=/tmp/puplsp" "--stdio")) :environment-fn (lambda() '(("BUNDLE_GEMFILE" . "/home/stefan/Apps/puppet-editor-services/Gemfile"))) :major-modes '(puppet-mode) :server-id 'puppet-languageserver)) (add-to-list 'lsp-language-id-configuration '(puppet-mode . "puppet-languageserver")) (lsp-register-client (make-lsp-client :new-connection (lsp-stdio-connection '("nix-shell" "-p" "nodePackages.yaml-language-server" "--run" "yaml-language-server --stdio")) :major-modes '(yaml-mode) :server-id 'nix-yls)) (add-to-list 'lsp-language-id-configuration '(yaml-mode . "yaml-language-server")) (lsp-register-client (make-lsp-client :new-connection (lsp-stdio-connection '("nix-shell" "-p" "nodePackages.typescript-language-server" "--run" "typescript-language-server --stdio")) :major-modes '(js2-mode) :server-id 'nix-tls)) (add-to-list 'lsp-language-id-configuration '(js2-mode . "nix-tls")) (lsp-register-client (make-lsp-client :new-connection (lsp-stdio-connection '("php" "/home/stefan/vendor/felixfbecker/language-server/bin/php-language-server.php")) :major-modes '(php-mode) :server-id 'php-custom)) (add-to-list 'lsp-language-id-configuration '(puppet-mode . "php-custom")) (setq lsp-auto-configure t lsp-auto-guess-root t lsp-enable-indentation t lsp-enable-on-type-formatting t lsp-before-save-edits t lsp-enable-snippet t ) ) (use-package flycheck :ensure t :init (global-flycheck-mode)) (use-package lsp-ui :ensure t :commands lsp-ui-mode) (use-package company-lsp :ensure t :commands company-lsp) (use-package lsp-ivy :ensure t) (use-package yasnippet :ensure t :config (yas-global-mode 1)) (use-package yasnippet-snippets :ensure t) (use-package smartparens :ensure t :config (smartparens-global-mode 1)) ;; magit (use-package evil-magit :ensure t) (use-package magit :ensure t) ;; general config (use-package general :ensure t :config (menu-bar-mode -1) (toggle-scroll-bar -1) (tool-bar-mode -1) (general-define-key :states '(normal visual insert emacs) :prefix "SPC" :non-normal-prefix "C-SPC" ;; simple command "SPC" 'counsel-M-x "'" '(iterm-focus :which-key "iterm") "?" '(iterm-goto-filedir-or-home :which-key "iterm - goto dir") "/" 'counsel-ag "TAB" '(foo/switch-to-last-buffer :which-key "prev buffer") ;; Applications "a" '(:ignore t :which-key "Applications") "ar" 'ranger "ad" 'dired ;; Buffers "b" '(:ignore t :which-key "Buffers") "bb" 'switch-to-buffer "bd" 'evil-delete-buffer "bn" 'next-buffer "bn" 'next-buffer "bs" 'foo/switch-to-scratch-buffer ;; Files "ff" 'counsel-find-file "fL" 'counsel-locate "fr" 'counsel-recentf "fR" 'foo/rename-current-buffer-file "fD" 'foo/delete-current-buffer-file "fc" 'foo/copy-file' ;; Git "g" '(:ignore t :which-key "Magit") "gfh" 'magit-log-buffer-file "gm" 'magit-dispatch-popup "gs" 'magit-status "gS" 'magit-stage-file "gU" 'magit-unstage-file ;; Jumps "j" '(:ignore t :which-key "Jump") "jj" 'avy-goto-char-2 ;; Langs "mf" 'lsp "mf" 'lsp-format-buffer "mi" 'lsp-organize-imports "mgg" 'lsp-find-definition "mh" 'lsp-describe-thing-at-point "mj" 'imenu "me" 'lsp-ui-flycheck-list "mn" 'flycheck-next-error "ms" 'lsp-ivy-workspace-symbol "mS" 'lsp-ivy-global-workspace-symbol ;; Projectile "p" '(:ignore t :which-key "Projectile") "p SPC" 'counsel-projectile "pb" 'counsel-projectile-switch-to-buffer "pd" 'counsel-projectile-find-dir "pp" 'counsel-projectile-switch-project "pf" 'counsel-fzf "pr" 'projectile-recentf ;; Swyper "s" '(:ignore t :which-key "Swyper") "ss" 'swiper "sb" 'swiper-all "sw" 'avy-goto-word-0 ;; Treemacs "ft" 'treemacs "fB" 'treemacs-bookmark "fT" 'treemacs-find-file "f M-t" 'treemacs-find-tag ;; Jira "jpg" 'org-jira-get-projects "jib" 'org-jira-browse-issue "jig" 'org-jira-get-issues "jij" 'org-jira-get-issues-from-custom-jql "jih" 'org-jira-get-issues-headonly "jiu" 'org-jira-update-issue "jiw" 'org-jira-progress-issue "jin" 'org-jira-progress-issue-next "jia" 'org-jira-assign-issue "jir" 'org-jira-refresh-issue "jiR" 'org-jira-refresh-issues-in-buffer "jic" 'org-jira-create-issue "jik" 'org-jira-copy-current-issue-key "jsc" 'org-jira-create-subtask "jsg" 'org-jira-get-subtasks "jcc" 'org-jira-add-comment "jcu" 'org-jira-update-comment "jwu" 'org-jira-update-worklogs-from-org-clocks "jtj" 'org-jira-todo-to-jira "jif" 'org-jira-get-issues-by-fixversion ;; Roam "rl" 'org-roam-buffer-toggle "rf" 'org-roam-node-find "rg" 'org-roam-graph "ri" 'org-roam-node-insert "rc" 'org-roam-capture "rj" 'org-roam-dailies-capture-today ;; Window "w" '(:ignore t :which-key "Window") "w=" 'balance-windows-area "wd" 'evil-window-delete "w " 'evil-window-down "wf" 'follow-mode "wF" 'make-frame "wh" 'evil-window-left "wH" 'evil-window-move-far-left "wj" 'evil-window-down "wJ" 'evil-window-move-very-bottom "wK" 'evil-window-move-very-top "wk" 'evil-window-up "w " 'evil-window-left "wL" 'evil-window-move-far-right "wl" 'evil-window-right "wm" 'foo/toggle-maximize-buffer "wo" 'other-frame "w " 'evil-window-right "w " 'evil-window-move-very-bottom "w " 'evil-window-move-far-left "w-" 'split-window-below "w/" 'split-window-right "w " 'evil-window-move-far-right "ws" 'split-window-below "wS" 'split-window-below-and-focus "w " 'evil-window-move-very-top "w " 'evil-window-up "wU" 'winner-redo "wu" 'winner-undo "wv" 'split-window-right "wV" 'split-window-right-and-focus "ww" 'other-window "wx" 'kill-buffer-and-window )) ;; custom functions (defun foo/toggle-maximize-buffer () "Maximize buffer." (interactive) (save-excursion (if (and (= 1 (length (window-list))) (assoc ?_ register-alist)) (jump-to-register ?_) (progn (window-configuration-to-register ?_) (delete-other-windows))))) (defun foo/switch-to-scratch-buffer (&optional arg) "Switch to the `*scratch*' buffer, creating it first if needed. if prefix argument ARG is given, switch to it in an other, possibly new window." (interactive "P") (let ((exists (get-buffer "*scratch*"))) (if arg (switch-to-buffer-other-window (get-buffer-create "*scratch*")) (switch-to-buffer (get-buffer-create "*scratch*"))))) (defun foo/switch-to-last-buffer () "Switch to the last buffer, allowes quick jumping between the last two." (interactive) (switch-to-buffer nil)) (defun foo/delete-current-buffer-file () "Remove file connected to current buffer and kill buffer." (interactive) (let ((filename (buffer-file-name)) (buffer (current-buffer)) (name (buffer-name))) (if (not (and filename (file-exists-p filename))) (ido-kill-buffer) (if (yes-or-no-p (format "Are you sure you want to delete this file: '%s'?" name)) (progn (delete-file filename t) (kill-buffer buffer) (when (projectile-project-p) (call-interactively #'projectile-invalidate-cache)) (message "File deleted: '%s'" filename)) (message "Canceled: File deletion"))))) (defun foo/rename-current-buffer-file (&optional arg) "Rename the current buffer and the file it is visiting. If the buffer isn't visiting a file, ask if it should be saved to a file, or just renamed. If called without a prefix argument (ARG), the prompt is initialized with the current directory instead of filename." (interactive "P") (let* ((name (buffer-name)) (filename (buffer-file-name))) (if (and filename (file-exists-p filename)) ;; the buffer is visiting a file (let* ((dir (file-name-directory filename)) (new-name (read-file-name "New name: " (if arg dir filename)))) (cond ((get-buffer new-name) (error "A buffer named '%s' already exists!" new-name)) (t (let ((dir (file-name-directory new-name))) (when (and (not (file-exists-p dir)) (yes-or-no-p (format "Create directory '%s'?" dir))) (make-directory dir t))) (rename-file filename new-name 1) (rename-buffer new-name) (set-visited-file-name new-name) (set-buffer-modified-p nil) (when (fboundp 'recentf-add-file) (recentf-add-file new-name) (recentf-remove-if-non-kept filename)) (when (projectile-project-p) (call-interactively #'projectile-invalidate-cache)) (message "File '%s' successfully renamed to '%s'" name (file-name-nondirectory new-name))))) ;; the buffer is not visiting a file (let ((key)) (while (not (memq key '(?s ?r))) (setq key (read-key (propertize (format (concat "Buffer '%s' is not visiting a file: " "[s]ave to file or [r]ename buffer?") name) 'face 'minibuffer-prompt))) (cond ((eq key ?s) ; save to file ;; this allows for saving a new empty (unmodified) buffer (unless (buffer-modified-p) (set-buffer-modified-p t)) (save-buffer)) ((eq key ?r) ; rename buffer (let ((new-name (read-string "New buffer name: "))) (while (get-buffer new-name) ;; ask to rename again, if the new buffer name exists (if (yes-or-no-p (format (concat "A buffer named '%s' already exists: " "Rename again?") new-name)) (setq new-name (read-string "New buffer name: ")) (keyboard-quit))) (rename-buffer new-name) (message "Buffer '%s' successfully renamed to '%s'" name new-name))) ;; ?\a = C-g, ?\e = Esc and C-[ ((memq key '(?\a ?\e)) (keyboard-quit)))))))) (defun foo/copy-file () "Write the file under new name." (interactive) (call-interactively 'write-file)) ;; other (custom-set-variables ;; custom-set-variables was added by Custom. ;; If you edit it by hand, you could mess it up, so be careful. ;; Your init file should contain only one such instance. ;; If there is more than one, they won't work right. '(custom-safe-themes '("711efe8b1233f2cf52f338fd7f15ce11c836d0b6240a18fffffc2cbd5bfe61b0" "01cf34eca93938925143f402c2e6141f03abb341f27d1c2dba3d50af9357ce70" "37144b437478e4c235824f0e94afa740ee2c7d16952e69ac3c5ed4352209eefb" "93ed23c504b202cf96ee591138b0012c295338f38046a1f3c14522d4a64d7308" "f7216d3573e1bd2a2b47a2331f368b45e7b5182ddbe396d02b964b1ea5c5dc27" "c4bdbbd52c8e07112d1bfd00fee22bf0f25e727e95623ecb20c4fa098b74c1bd" "f2927d7d87e8207fa9a0a003c0f222d45c948845de162c885bf6ad2a255babfd" "71e5acf6053215f553036482f3340a5445aee364fb2e292c70d9175fb0cc8af7" "99ea831ca79a916f1bd789de366b639d09811501e8c092c85b2cb7d697777f93" "e074be1c799b509f52870ee596a5977b519f6d269455b84ed998666cf6fc802a" "ca849ae0c889eb918785cdc75452b1e11a00848a5128a95a23872e0119ccc8f4" "1ca1f43ca32d30b05980e01fa60c107b02240226ac486f41f9b790899f6f6e67" "55257ccc6763185dde2146bcc5aa2b83130cc55042c45daaf5efe3c3137b578f" "5091eadbb87fa0a168a65f2c3e579d1a648d764f12ab9d3ab7bdefca709cd2a5" "5a411e7cb2d7955b28c514cd5b75782c6dd4ba027089fec17a2573405b0fdd5c" "aed6332e9a38b49bb044b994e8be0d57a2f67ff6ca96f5ce8e0130562c4cc233" "2d1fe7c9007a5b76cea4395b0fc664d0c1cfd34bb4f1860300347cdad67fb2f9" "7dc3fe8fadb914563790a3fbe587fd455626442f66da333ea4de2c455feefb98" "37ba833442e0c5155a46df21446cadbe623440ccb6bbd61382eb869a2b9e9bf9" "09cadcc2784baa744c6a7c5ebf2a30df59c275414768b0719b800cabd8d1b842" "427fa665823299f8258d8e27c80a1481edbb8f5463a6fb2665261e9076626710" "614e5089876ea69b515c50b6d7fa0a37eb7ed50fda224623ec49e1c91a0af6a1" "93a0885d5f46d2aeac12bf6be1754faa7d5e28b27926b8aa812840fe7d0b7983" "b0fd04a1b4b614840073a82a53e88fe2abc3d731462d6fde4e541807825af342" "cdb3e7a8864cede434b168c9a060bf853eeb5b3f9f758310d2a2e23be41a24ae" "ef4edbfc3ec509612f3cf82476beddd2aeb3da7bdc3a35726337a0cc838a4ef4" "a16e816774b437acb78beb9916a60ea236cfcd05784227a7d829623f8468c5a2" "8c847a5675ece40017de93045a28ebd9ede7b843469c5dec78988717f943952a" "e3c87e869f94af65d358aa279945a3daf46f8185f1a5756ca1c90759024593dd" "db10381a554231a40b7474eaac28bd58f05067faacce3b25d294bb179a3511a1" "34c99997eaa73d64b1aaa95caca9f0d64229871c200c5254526d0062f8074693" "868abc288f3afe212a70d24de2e156180e97c67ca2e86ba0f2bf9a18c9672f07" default)) '(package-selected-packages '(direnv lsp-ivy bazel-mode rainbow-mode highlight-indentation k8s-mode darkokai-theme monokai-pro-theme php-mode puppet-mode smartparens yaml-mode ivy-hydra ivy-rich evy use-package general evil avy)) '(require-final-newline t)) (custom-set-faces ;; custom-set-faces was added by Custom. ;; If you edit it by hand, you could mess it up, so be careful. ;; Your init file should contain only one such instance. ;; If there is more than one, they won't work right. ) (provide 'init) ;;; init.el ends here