Skip to content

Instantly share code, notes, and snippets.

@kliph
Last active April 3, 2024 13:53
Show Gist options
  • Save kliph/0f0d513c3d66197841787593852427a4 to your computer and use it in GitHub Desktop.
Save kliph/0f0d513c3d66197841787593852427a4 to your computer and use it in GitHub Desktop.
My local emacs config. See https://github.com/promptworks/dotfiles for base emacs configuration.
;; -*- mode: emacs-lisp -*-
;;; Emacs is a platform written in 1976 (yes, almost half a century ago) for
;;; writing software to make you more productive, masquerading as a text
;;; editor. -- Steve Yegge
;;; Use Paredit
(unless (package-installed-p 'paredit)
(package-install 'paredit))
(require 'paredit)
(add-hook 'emacs-lisp-mode-hook #'enable-paredit-mode)
(add-hook 'clojure-mode-hook #'enable-paredit-mode)
(require 'ruby-mode)
;;; Opt out of hard indentation for content https://orgmode.org/manual/Hard-indentation.html
(setq org-adapt-indentation nil)
(defun kliph/paredit-newline-dwim ()
"Do what I mean when I want a newline. Sometimes I want to see
the evaluation of the last sexp. This function is meant to be
bound to C-j in the `paredit-mode-map'."
(interactive)
(cond ((and (eolp)
(not (eq (kliph/get-cur-buffer-major-mode) 'clojure-mode)))
(eval-print-last-sexp))
(t (paredit-newline))))
(defun kliph/paredit-forward-up-dwim ()
"Don't throw a silly scan error when I just want to move to the
next sexp. This function is meant to be bound to C-M-n in the
`paredit-mode-map'."
(interactive)
(cond ((or (eolp) (bolp)) (paredit-forward))
(t (paredit-forward-up))))
(defun kliph/paredit-backward-down-dwim ()
"Don't throw a silly scan error when I just want to move back
through sexps. This function is meant to be bound to C-M-p in the
`paredit-mode-map'."
(interactive)
(cond ((not (looking-back "\)")) (paredit-backward))
(t (paredit-backward-down))))
(define-key paredit-mode-map (kbd "C-j") 'kliph/paredit-newline-dwim)
(define-key paredit-mode-map (kbd "C-M-n") 'kliph/paredit-forward-up-dwim)
(define-key paredit-mode-map (kbd "C-M-p") 'kliph/paredit-backward-down-dwim)
(define-key paredit-mode-map (kbd "C->") 'paredit-forward-barf-sexp)
(define-key paredit-mode-map (kbd "C-<") 'paredit-backward-barf-sexp)
(global-set-key (kbd "C-M-s-9") 'paredit-mode)
;;; Show line numbers and cols in bottom bar
(setq line-number-mode 1)
(setq column-number-mode 1)
(unless (package-installed-p 'ace-window)
(package-install 'ace-window))
(require 'ace-window)
(global-set-key (kbd "M-`") 'ace-window)
(setq aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l))
;;; Bye bye white space
(add-hook 'before-save-hook 'delete-trailing-whitespace)
(global-display-line-numbers-mode)
(unless (package-installed-p 'clojure-mode)
(package-install 'clojure-mode))
(require 'clojure-mode)
(unless (package-installed-p 'cider)
(package-install 'cider))
(require 'cider)
(add-to-list 'exec-path "/usr/local/bin")
(show-paren-mode 1)
(unless (package-installed-p 'web-mode)
(package-install 'web-mode))
(require 'web-mode)
(add-to-list 'auto-mode-alist '("\\.erb" . web-mode))
(add-to-list 'auto-mode-alist '("\\.html.erb" . web-mode))
(add-to-list 'auto-mode-alist '("\\.tsx" . web-mode))
(setq web-mode-enable-current-element-highlight 't)
(setq web-mode-enable-auto-quoting nil)
(add-hook 'web-mode-hook
(lambda ()
(when (or (string-equal "tsx" (file-name-extension buffer-file-name))
(string-equal "js" (file-name-extension buffer-file-name)))
(setup-tide-mode))))
(define-key web-mode-map (kbd "C-c /") 'web-mode-element-close)
(define-key web-mode-map (kbd "s-r") 'web-mode-element-rename)
(defun kliph/toggle-keyword-string ()
"Convert the string or keyword at point to keyword or string."
(interactive)
(let ((original-point (point)))
(while (and (> (point) 1)
(not (equal "\'" (buffer-substring-no-properties (point) (+ 1 (point)))))
(not (equal ":" (buffer-substring-no-properties (point) (+ 1 (point))))))
(backward-char))
(cond
((equal 1 (point))
(error "Beginning of file reached, this was probably a mistake"))
((equal "\'" (buffer-substring-no-properties (point) (+ 1 (point))))
(insert ":" (substring (kliph/delete-and-extract-dwim) 1 -1)))
((equal ":" (buffer-substring-no-properties (point) (+ 1 (point))))
(insert "\'" (substring (kliph/delete-and-extract-dwim) 1) "\'")))
(goto-char original-point)))
(define-key ruby-mode-map (kbd "C-:") 'kliph/toggle-keyword-string)
(define-key web-mode-map (kbd "C-:") 'kliph/toggle-keyword-string)
(unless (package-installed-p 'tide)
(package-install 'tide))
(require 'tide)
(unless (package-installed-p 'flycheck)
(package-install 'flycheck))
(require 'flycheck)
(flycheck-add-mode 'javascript-eslint 'web-mode)
;;; Check typescript first and go on to check eslint if there are no errors.
(flycheck-add-next-checker 'tsx-tide '(warning . javascript-eslint))
(add-hook 'python-mode-hook
(lambda ()
(flycheck-mode 1)
(setq flycheck-checker 'python-pylint)))
(add-hook 'ruby-mode-hook
'flycheck-mode)
(add-hook 'js2-mode-hook
'flycheck-mode)
(add-hook 'org-src-mode-hook
(lambda ()
(flycheck-mode 0)))
(add-hook 'sql-mode-hook
'flycheck-mode)
(defun kliph/use-eslint-from-node-modules ()
(let* ((root (locate-dominating-file
(or (buffer-file-name) default-directory)
"node_modules"))
(eslint (and root
(expand-file-name "node_modules/.bin/eslint"
root))))
(when (and eslint (file-executable-p eslint))
(setq-local flycheck-javascript-eslint-executable eslint))))
(add-hook 'flycheck-mode-hook #'kliph/use-eslint-from-node-modules)
;;; See also http://www.flycheck.org/en/latest/user/syntax-checkers.html#variable-flycheck-checker for setting eslint as Flycheck checker in .dir-locals.el
(unless (package-installed-p 'rjsx-mode)
(package-install 'rjsx-mode))
(require 'rjsx-mode)
(global-set-key (kbd "C-.") 'rjsx-mode)
(global-set-key (kbd "s-.") 'js2-mode)
(add-to-list 'auto-mode-alist '("\\.js\\'" . rjsx-mode))
(setq ispell-program-name "aspell")
(require 'evil)
(define-key evil-normal-state-map (kbd "C-p") 'projectile-find-file)
(setq visible-bell nil)
(setq ring-bell-function
(lambda ()
(invert-face 'mode-line)
(run-with-timer 0.1 nil 'invert-face 'mode-line)))
(unless (package-installed-p 'expand-region)
(package-install 'expand-region))
(require 'expand-region)
(global-set-key (kbd "C-=") 'er/expand-region)
(eval-after-load 'rjsx-mode '(require 'web-mode-expansions))
;;; How to do this without setting the theme to solarized?
(defun kliph/load-solarized-light-theme-dwim ()
(interactive)
(load-theme 'solarized-light)
(setq solarized-use-variable-pitch nil
solarized-scale-org-headlines nil)
(add-to-list 'default-frame-alist '(ns-appearance . light))
(set-face-background 'hl-line "#EEE8D4"))
(defun kliph/load-solarized-dark-theme-dwim ()
(interactive)
(load-theme 'solarized-dark)
(setq solarized-use-variable-pitch nil
solarized-scale-org-headlines nil)
(set-face-background 'hl-line "#03333F"))
(unless (package-installed-p 'panda-theme)
(package-install 'panda-theme))
(require 'panda-theme)
(defun kliph/load-panda-theme-dwim ()
(interactive)
(load-theme 'panda)
(let ((bg- "#1A1816")
(bg "#292A2B")
(bg+ "#404954"))
;; (set-face-background 'linum bg)
(set-face-background 'mode-line bg)
(set-face-attribute 'mode-line nil
:overline bg-
:underline bg+
:background bg+
:box bg)
(set-face-background 'mode-line-inactive bg-)
(set-face-attribute 'mode-line-inactive nil
:overline bg+
:underline bg-
:box bg)
(set-face-background 'hl-line bg+)
(set-face-background 'magit-diff-hunk-heading bg)
(set-face-background 'magit-diff-hunk-heading-highlight bg)
(set-face-background 'magit-diff-file-heading-highlight bg)))
(defalias 'solarize 'kliph/load-solarized-light-theme-dwim)
(defalias 'solarize-dark 'kliph/load-solarized-dark-theme-dwim)
(defalias 'panda 'kliph/load-panda-theme-dwim)
(defalias 'panda-panda-panda-panda-panda-panda-panda 'panda)
(unless (package-installed-p 'rvm)
(package-install 'rvm))
(require 'rvm)
(rvm-use-default)
(unless (package-installed-p 'rubocop)
(package-install 'rubocop))
(require 'rubocop)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; http://stackoverflow.com/questions/5543989/pylint-not-working-with-emacs-gui-on-os-x-works-from-command-line/5558223#5558223
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun set-exec-path-from-shell-PATH ()
(let ((path-from-shell (replace-regexp-in-string
"[ \t\n]*$"
""
(shell-command-to-string "/bin/zsh --login -i -c 'echo $PATH'"))))
(setenv "PATH" path-from-shell)
(setq exec-path (split-string path-from-shell path-separator))))
(when (memq window-system '(mac ns))
;; When started from Emacs.app or similar, ensure $PATH
;; is the same the user would see in Terminal.app
(set-exec-path-from-shell-PATH))
(shell-command "ssh-add -K ~/.ssh/id_ed25519")
(unless (package-installed-p 'haml-mode)
(package-install 'haml-mode))
(require 'haml-mode)
(require 'ox-md)
(defun kliph/unfill-paragraphs-to-be-one-line (min max)
"Fill individual paragraphs with a large fill column so they're
on one line. Keeps paragraph breaks intact."
(interactive "r")
(let ((fill-column 100000))
(fill-individual-paragraphs min max)))
(unless (package-installed-p 'htmlize)
(package-install 'htmlize))
(require 'htmlize)
(unless (package-installed-p 's)
(package-install 's))
(require 's)
(defun kliph/message-git-user ()
"Remind me of the current git user name. Meant to be added to
the `magit-mode-hook'."
(message (s-trim
(format "Current git user name is: %s"
(shell-command-to-string "git config user.name")))))
(add-hook 'magit-mode-hook 'kliph/message-git-user)
;; https://github.com/toctan/toggle-quotes.el
(add-to-list 'load-path "~/.emacs.d/toggle-quotes/")
(require 'toggle-quotes)
(global-set-key (kbd "C-'") 'toggle-quotes)
(global-set-key (kbd "C-\"") 'toggle-quotes)
(defun toggle-camelcase-underscores ()
"Toggle between camelcase and underscore notation for the symbol at point."
(interactive)
(save-excursion
(let* ((bounds (bounds-of-thing-at-point 'symbol))
(start (car bounds))
(end (cdr bounds))
(currently-using-underscores-p (progn (goto-char start)
(re-search-forward "_" end t))))
(if currently-using-underscores-p
(progn
(upcase-initials-region start end)
(replace-string "_" "" nil start end)
(downcase-region start (1+ start)))
(replace-regexp "\\([A-Z]\\)" "_\\1" nil (1+ start) end)
(downcase-region start (cdr (bounds-of-thing-at-point 'symbol)))))))
(unless (package-installed-p 'rg)
(package-install 'rg))
(require 'rg)
(global-set-key (kbd "M-s-.") 'rg-dwim)
(unless (package-installed-p 'slim-mode)
(package-install 'slim-mode))
(require 'slim-mode)
(unless (package-installed-p 'dumb-jump)
(package-install 'dumb-jump))
(require 'dumb-jump)
(define-key ruby-mode-map (kbd "M-.") 'dumb-jump-go)
(define-key ruby-mode-map (kbd "M-,") 'dumb-jump-back)
;;; The default keybinding C-M-p clobbers some movement from paredit.
;;; Let's prefer paredit keybinding because I use them more
;;; frequently. I don't think the `(kbd "C-s-p")' actually works
;;; because of how OS X sends keyboard signals to emacs. So if I
;;; start to use this keybinding it may make sense to remap it
;;; further.
(define-key dumb-jump-mode-map (kbd "C-s-p") 'dumb-jump-back)
(define-key dumb-jump-mode-map (kbd "C-M-p") nil)
(unless (package-installed-p 'swift-mode)
(package-install 'swift-mode))
(require 'swift-mode)
(defun kliph/delete-and-extract-dwim ()
"Delete the surrounding sexp and return it."
(let ((begin (point)))
(forward-sexp)
(let ((result (buffer-substring begin (point))))
(delete-region begin (point))
result)))
(unless (package-installed-p 'markdown-mode)
(package-install 'markdown-mode))
(require 'markdown-mode)
(define-key markdown-mode-map (kbd "C-<return>") 'markdown-insert-header-dwim)
(define-key markdown-mode-map (kbd "C-c C-l") 'markdown-insert-link)
(when (memq window-system '(mac ns))
(toggle-scroll-bar -1))
(add-hook 'org-mode-hook 'turn-on-visual-line-mode)
(add-hook 'org-mode-hook 'flyspell-mode)
(add-hook 'org-mode-hook (lambda ()
(setq-local electric-pair-inhibit-predicate
`(lambda (c)
(if (char-equal c ?\() t (,electric-pair-inhibit-predicate c))))))
(add-hook 'org-mode-hook #'(lambda () (electric-indent-local-mode 0)))
(add-hook 'markdown-mode-hook 'turn-on-visual-line-mode)
(add-hook 'markdown-mode-hook 'flyspell-mode)
(unless (package-installed-p 'json-reformat)
(package-install 'json-reformat))
(require 'json-reformat)
(unless (package-installed-p 'emojify)
(package-install 'emojify))
(require 'emojify)
(defun to-underscore ()
(interactive)
(progn (replace-regexp "\\([A-Z]\\)" "_\\1" nil (region-beginning) (region-end))
(downcase-region (region-beginning) (region-end))))
(defalias 'camelCase-to-underscore 'to-underscore)
(defun to-kebab ()
(interactive)
(progn (replace-regexp "\\([A-Z]\\)" "-\\1" nil (region-beginning) (region-end))
(downcase-region (region-beginning) (region-end))))
(defun mapcar-head (fn-head fn-rest list)
"Like MAPCAR, but applies a different function to the first element."
(if list
(cons (funcall fn-head (car list)) (mapcar fn-rest (cdr list)))))
(defun underscore-to-camelCase ()
(interactive)
(let* ((s (buffer-substring (region-beginning) (region-end)))
(camel-string (mapconcat 'identity (mapcar-head
'downcase
'(lambda (word) (capitalize (downcase word)))
(split-string s "_"))
"")))
(delete-region (region-beginning) (region-end))
(insert camel-string)))
(defun underscore-to-CamelCase ()
(interactive)
(let* ((s (buffer-substring (region-beginning) (region-end)))
(camel-string (mapconcat 'identity (mapcar-head
'(lambda (word) (capitalize (downcase word)))
'(lambda (word) (capitalize (downcase word)))
(split-string s "_"))
"")))
(delete-region (region-beginning) (region-end))
(insert camel-string)))
(unless (package-installed-p 'json-mode)
(package-install 'json-mode))
(require 'json-mode)
(add-to-list 'auto-mode-alist '("\\.json\\'" . json-mode))
(add-to-list 'auto-mode-alist '("\\.json" . json-mode))
(scroll-bar-mode -1)
(add-hook 'cider-mode-hook 'turn-on-eldoc-mode)
(add-hook 'python-mode-hook
(lambda ()
(setq-local completion-at-point-functions nil)))
;;; Ensure you have proselint installed via homebrew
(when (executable-find "proselint")
(add-hook 'markdown-mode-hook
(lambda ()
(flycheck-mode 1)
(setq flycheck-checker 'proselint))))
(require 'ob-clojure)
(setq org-babel-clojure-backend 'cider)
(require 'ob-python)
(defun setup-tide-mode ()
(interactive)
(tide-setup)
(flycheck-mode +1)
(setq flycheck-check-syntax-automatically '(save mode-enabled))
(eldoc-mode +1)
(tide-hl-identifier-mode +1)
;; company is an optional dependency. You have to
;; install it separately via package-install
;; `M-x package-install [ret] company`
(company-mode +1))
;; aligns annotation to the right hand side
(setq company-tooltip-align-annotations t)
;; formats the buffer before saving
(add-hook 'before-save-hook 'tide-format-before-save)
(add-hook 'typescript-mode-hook #'setup-tide-mode)
;;; See: https://github.com/ananthakumaran/tide/issues/114
(setq tide-tsserver-executable nil)
(define-key tide-mode-map (kbd "s-r") 'tide-rename-symbol)
(setq-default tide-user-preferences '(:importModuleSpecifierPreference
"non-relative"
:includeCompletionsForModuleExports t
:includeCompletionsWithInsertText t
:allowTextChangesInNewFiles t))
(defalias 'tide-find-references 'tide-references)
(setq kliph/yarn-lint-command "yarn eslint %s --fix")
(put 'kliph/yarn-lint-command 'safe-local-variable #'stringp)
(defun kliph/yarn-lint ()
(interactive)
(shell-command (format kliph/yarn-lint-command buffer-file-name))
(revert-buffer nil 't))
(defun kliph/rubocop-lint ()
(interactive)
(shell-command (format "rubocop -a %s" buffer-file-name))
(revert-buffer nil 't))
(global-set-key (kbd "M-s-l") 'kliph/yarn-lint)
(global-set-key (kbd "M-s-r") 'kliph/rubocop-lint)
(global-set-key (kbd "s-l") 'goto-line)
;;; Transparent titlebar
;; https://github.com/d12frosted/homebrew-emacs-plus/blob/master/Formula/emacs-plus.rb#L98
;; https://github.com/d12frosted/homebrew-emacs-plus/issues/55
;; https://www.gnu.org/software/emacs/manual/html_node/elisp/Properties-in-Mode.html#Properties-in-Mode
(when (memq window-system '(mac ns))
(add-to-list 'default-frame-alist '(ns-appearance . dark))
(add-to-list 'default-frame-alist '(ns-transparent-titlebar . t)))
(unless (package-installed-p 'sws-mode)
(package-install 'sws-mode))
(require 'sws-mode)
(unless (package-installed-p 'stylus-mode)
(package-install 'stylus-mode))
(require 'stylus-mode)
(define-key git-commit-mode-map (kbd "s-.") 'text-mode)
(define-key git-commit-mode-map (kbd "C-.") 'text-mode)
(unless (package-installed-p 'use-package)
(package-install 'use-package))
(require 'use-package)
(setq lsp-keymap-prefix "s-y")
(unless (package-installed-p 'lsp-mode)
(package-install 'lsp-mode))
(require 'lsp-mode)
(add-hook 'js2-mode-hook
'lsp)
(add-hook 'rjsx-mode-hook
'lsp)
(add-hook 'python-mode-hook
'lsp)
;;; I've run into issues where Emacs is using a different version of node to what the project specifies in `.nvmrc'. I haven't come up with a good solution for this.
;;; I just check which version emacs is using via `M-! node --version' and then ensure the dependencies are installed for that version via switching to it using nvm and running `npm i -g typescript-language-server typescript'
;;; I've run into problems resolving aliases in JavaScript projects using jsconfig.json. https://github.com/microsoft/vscode/issues/16320#issuecomment-540415092 was helpful.
;;;
;;; My current jsonconfig.json looks like:
;; {
;; "compilerOptions": {
;; "baseUrl": "./",
;; "jsx": "preserve",
;; "paths": {
;; "models/*": ["src/scripts/domain/models/*"],
;; ...
;; }
;; }
;; }
(define-key lsp-mode-map (kbd "s-r") 'lsp-rename)
(define-key lsp-mode-map (kbd "M-.") 'lsp-find-definition)
(add-to-list 'auto-mode-alist '("\\.Rmd" . markdown-mode))
(unless (package-installed-p 'js2-refactor)
(package-install 'js2-refactor))
(require 'js2-refactor)
(add-hook 'js2-mode-hook #'js2-refactor-mode)
;;; I'd like to use their kill but it doesn't work well with styled component template strings
(define-key js2-refactor-mode-map (kbd "s->") 'js2r-toggle-arrow-function-and-expression)
(define-key js2-refactor-mode-map (kbd "C-)") 'js2r-forward-slurp)
;;; Save session
(when (display-graphic-p)
(desktop-save-mode 1))
(setq js-indent-level 2)
(setq indent-tabs-mode nil)
(defun kliph/highlight-current-line ()
(interactive)
(if (display-graphic-p)
(global-hl-line-mode 1)
(global-hl-line-mode -1)))
(global-set-key (kbd "M-s-y") 'kliph/highlight-current-line)
(require 'uniquify)
(setq uniquify-buffer-name-style 'forward)
(setq uniquify-separator "/")
(setq uniquify-after-kill-buffer-p t)
(setq uniquify-ignore-buffers-re "^\\*")
(lsp-register-client
(make-lsp-client :new-connection (lsp-stdio-connection '("/usr/local/bin/terraform-ls" "serve"))
:major-modes '(terraform-mode)
:server-id 'terraform-ls))
(add-hook 'terraform-mode-hook #'lsp)
(add-hook 'yaml-mode-hook #'highlight-indentation-mode)
(global-set-key (kbd "C-x t t") 'window-swap-states)
(projectile-register-project-type 'lein-test '("project.clj")
:compile "lein compile"
:test "lein test"
:test-suffix "_test")
(unless (package-installed-p 'go-mode)
(package-install 'go-mode))
(require 'go-mode)
(electric-pair-mode 1)
;;; From https://geeksocket.in/posts/emacs-lsp-go/
(defun lsp-go-install-save-hooks ()
(add-hook 'before-save-hook #'lsp-format-buffer t t)
(add-hook 'before-save-hook #'lsp-organize-imports t t))
(add-hook 'go-mode-hook #'lsp-go-install-save-hooks)
(add-hook 'go-mode-hook #'lsp-deferred)
(add-hook 'go-mode-hook #'yas-minor-mode-on)
(add-hook 'go-mode-hook (lambda () (electric-pair-mode 0)))
(add-hook 'go-mode-hook (lambda () (flycheck-add-next-checker 'lsp 'golangci-lint)))
(define-key org-mode-map (kbd "C-c s") 'org-insert-structure-template)
(define-key org-mode-map (kbd "C-c C-s") 'org-insert-structure-template)
(define-key org-mode-map (kbd "C-c M-p") 'org-previous-visible-heading)
(define-key org-mode-map (kbd "C-c M-n") 'org-next-visible-heading)
(define-key web-mode-map (kbd "C-c C-e C-r") 'web-mode-element-rename)
(define-key rjsx-mode-map (kbd "C-c C-e C-r") 'rjsx-rename-tag-at-point)
(define-key rjsx-mode-map (kbd "C-s-r") 'rjsx-rename-tag-at-point)
(setq lsp-file-watch-threshold 3000)
(setq sh-basic-offset 2)
(global-set-key (kbd "M-_") 'undo-redo)
;; See https://github.com/bbatsov/projectile/commit/981ef7de7cd4d2465e95ae649993561783d85bc8
(setq projectile-git-submodule-command nil)
(define-key web-mode-map (kbd "C-c C-r") 'tide-find-references)
(define-key rjsx-mode-map (kbd "C-c C-r") 'lsp-find-references)
(define-key go-mode-map (kbd "C-c C-r") 'lsp-find-references)
(unless (package-installed-p 'rainbow-delimiters)
(package-install 'rainbow-delimiters))
(setq backup-directory-alist '(("." . "~/.emacs.d/backups")))
;;; https://www.blogbyben.com/2022/05/gotcha-emacs-on-mac-os-too-many-files.html
(defun file-notify-rm-all-watches ()
"Remove all existing file notification watches from Emacs."
(interactive)
(maphash
(lambda (key _value)
(file-notify-rm-watch key))
file-notify-descriptors)
(message "File notification watches removed."))
(global-set-key (kbd "C-x &") 'file-notify-rm-all-watches)
(unless (package-installed-p 'string-inflection)
(package-install 'string-inflection-all-cycle))
(require 'string-inflection)
(global-set-key (kbd "C-c i") 'string-inflection-cycle)
(global-set-key (kbd "C-c C") 'string-inflection-camelcase) ;; Force to CamelCase
(global-set-key (kbd "C-c L") 'string-inflection-lower-camelcase) ;; Force to lowerCamelCase
(setq backup-directory-alist
`((".*" . "~/.emacs-auto-saves")))
(setq auto-save-file-name-transforms
`((".*" "~/.emacs-auto-saves" t)))
(unless (package-installed-p 'editorconfig)
(package-install 'editorconfig))
(unless (package-installed-p 's)
(package-install 's))
;;; Installed by cloning the repo here https://github.com/zerolfx/copilot.el to ~/.emacs.d
(add-to-list 'load-path "~/.emacs.d/copilot.el/")
(require 'copilot)
(add-hook 'prog-mode-hook 'copilot-mode)
(with-eval-after-load 'company
;; disable inline previews
(delq 'company-preview-if-just-one-frontend company-frontends))
(define-key copilot-completion-map (kbd "C-<tab>") 'copilot-accept-completion)
(define-key copilot-completion-map (kbd "C-TAB") 'copilot-accept-completion)
(global-set-key (kbd "s-]") 'copilot-mode)
;;; By default copilot checks if evil is in insert mode. Since I'm not using
;;; evil, this causes issues. If I do use evil in the future, I can add a hook
;;; to update the predicates in my keybindings that invoke evil mode. See
;;; https://github.com/zerolfx/copilot.el/pull/124
(setq copilot-enable-predicates '(copilot--buffer-changed))
;;; Don't display copilot completions when company completions are active
(add-to-list 'copilot-disable-display-predicates #'company--active-p)
(add-hook 'company-pre-command-hook #'copilot-clear-overlay)
(add-to-list 'load-path "~/.emacs.d/flycheck-golangci-lint/")
(require 'flycheck-golangci-lint)
(eval-after-load 'flycheck
'(add-hook 'flycheck-mode-hook #'flycheck-golangci-lint-setup))
(defun kliph/character-uppercase-p (char)
"Return t if CHAR is an uppercase character."
(eq (upcase char) char))
(defun kliph/toggle-case ()
"Toggle the case of the character at point."
(interactive)
(let ((char (char-after)))
(if (kliph/character-uppercase-p char)
(downcase-region (point) (+ 1 (point)))
(upcase-region (point) (+ 1 (point))))))
(global-set-key (kbd "C-`") 'kliph/toggle-case)
(global-set-key (kbd "C-~") 'kliph/toggle-case)
(defalias 'lsp-restart-workspace 'lsp-workspace-restart)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment