(use-package vertico
:custom (vertico-cycle t)
:init (vertico-mode))
(use-package savehist
:init (savehist-mode))
;; A few more useful configurations...
(use-package emacs
:init
;; Add prompt indicator to `completing-read-multiple'.
;; Alternatively try `consult-completing-read-multiple'.
(defun crm-indicator (args)
(cons (concat "[CRM] " (car args)) (cdr args)))
(advice-add #'completing-read-multiple :filter-args #'crm-indicator)
;; Do not allow the cursor in the minibuffer prompt
(setq minibuffer-prompt-properties
'(read-only t cursor-intangible t face minibuffer-prompt))
(add-hook 'minibuffer-setup-hook #'cursor-intangible-mode)
;; Emacs 28: Hide commands in M-x which do not work in the current mode.
;; Vertico commands are hidden in normal buffers.
(setq read-extended-command-predicate
#'command-completion-default-include-p)
;; Enable recursive minibuffers
(setq enable-recursive-minibuffers t))
https://github.com/minad/consult/wiki#minads-orderless-configuration
(use-package orderless
:demand t
:config
(defvar +orderless-dispatch-alist
'((?% . char-fold-to-regexp)
(?! . orderless-without-literal)
(?`. orderless-initialism)
(?= . orderless-literal)
(?~ . orderless-flex)))
;; Recognizes the following patterns:
;; * ~flex flex~
;; * =literal literal=
;; * %char-fold char-fold%
;; * `initialism initialism`
;; * !without-literal without-literal!
;; * .ext (file extension)
;; * regexp$ (regexp matching at end)
(defun +orderless-dispatch (pattern index _total)
(cond
;; Ensure that $ works with Consult commands, which add disambiguation suffixes
((string-suffix-p "$" pattern)
`(orderless-regexp . ,(concat (substring pattern 0 -1) "[\x100000-\x10FFFD]*$")))
;; File extensions
((and
;; Completing filename or eshell
(or minibuffer-completing-file-name
(derived-mode-p 'eshell-mode))
;; File extension
(string-match-p "\\`\\.." pattern))
`(orderless-regexp . ,(concat "\\." (substring pattern 1) "[\x100000-\x10FFFD]*$")))
;; Ignore single !
((string= "!" pattern) `(orderless-literal . ""))
;; Prefix and suffix
((if-let (x (assq (aref pattern 0) +orderless-dispatch-alist))
(cons (cdr x) (substring pattern 1))
(when-let (x (assq (aref pattern (1- (length pattern))) +orderless-dispatch-alist))
(cons (cdr x) (substring pattern 0 -1)))))))
;; Define orderless style with initialism by default
(orderless-define-completion-style +orderless-with-initialism
(orderless-matching-styles '(orderless-initialism orderless-literal orderless-regexp)))
;; You may want to combine the `orderless` style with `substring` and/or `basic`.
;; There are many details to consider, but the following configurations all work well.
;; Personally I (@minad) use option 3 currently. Also note that you may want to configure
;; special styles for special completion categories, e.g., partial-completion for files.
;;
;; 1. (setq completion-styles '(orderless))
;; This configuration results in a very coherent completion experience,
;; since orderless is used always and exclusively. But it may not work
;; in all scenarios. Prefix expansion with TAB is not possible.
;;
;; 2. (setq completion-styles '(substring orderless))
;; By trying substring before orderless, TAB expansion is possible.
;; The downside is that you can observe the switch from substring to orderless
;; during completion, less coherent.
;;
;; 3. (setq completion-styles '(orderless basic))
;; Certain dynamic completion tables (completion-table-dynamic)
;; do not work properly with orderless. One can add basic as a fallback.
;; Basic will only be used when orderless fails, which happens only for
;; these special tables.
;;
;; 4. (setq completion-styles '(substring orderless basic))
;; Combine substring, orderless and basic.
;;
(setq completion-styles '(orderless)
completion-category-defaults nil
;;; Enable partial-completion for files.
;;; Either give orderless precedence or partial-completion.
;;; Note that completion-category-overrides is not really an override,
;;; but rather prepended to the default completion-styles.
;; completion-category-overrides '((file (styles orderless partial-completion))) ;; orderless is tried first
completion-category-overrides '((file (styles partial-completion)) ;; partial-completion is tried first
;; enable initialism by default for symbols
(command (styles +orderless-with-initialism))
(variable (styles +orderless-with-initialism))
(symbol (styles +orderless-with-initialism)))
orderless-component-separator #'orderless-escapable-split-on-space ;; allow escaping space with backslash!
orderless-style-dispatchers '(+orderless-dispatch)))
(use-package company
:commands company-abort
:init (global-company-mode 1)
:config
(custom-set-faces
'(company-tooltip-common
((t (:inhirit company-tooltip :weight bold :underline nil))))
'(company-tooltip-common-selection
((t (:inhirit company-tooltip-selection :weight bold :underline nil)))))
:custom ((company-tooltip-align-annotations t)
(company-tooltip-limit 15)
(company-idle-delay 0.0)
(company-echo-delay 0)
(company-minimum-prefix-length 1)
(company-require-match nil)
(company-dabbrev-ignore-case nil)
(company-dabbrev-downcase nil)))
(use-package company-box
:hook (company-mode . company-box-mode))
(use-package marginalia
:after vertico
:custom (marginalia-annotators '(marginalia-annotators-heavy marginalia-annotators-light nil))
:init (marginalia-mode))
(use-package which-key
:config
(setq which-key-idle-delay 0.25
which-key-idle-secondary-delay 0.05
which-key-show-remaining-keys nil)
:init (which-key-mode)
:bind ("C-c c w" . which-key-show-major-mode))
(use-package avy
:bind ("C-:" . avy-goto-char))
(use-package embark
:ensure t
:bind
(("C-." . embark-act) ;; pick some comfortable binding
("C-;" . embark-dwim) ;; good alternative: M-.
("C-h B" . embark-bindings)) ;; alternative for `describe-bindings'
:init
;; Optionally replace the key help with a completing-read interface
(setq prefix-help-command #'embark-prefix-help-command)
:config
;; Hide the mode line of the Embark live/completions buffers
(add-to-list 'display-buffer-alist
'("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
nil
(window-parameters (mode-line-format . none)))))
(use-package embark-consult
:ensure t
:after (embark consult)
:demand t ; only necessary if you have the hook below
;; if you want to have consult previews as you move around an
;; auto-updating embark collect buffer
:hook (embark-collect-mode . consult-preview-at-point-mode))
(defun embark-which-key-indicator ()
"An embark indicator that displays keymaps using which-key.
The which-key help message will show the type and value of the
current target followed by an ellipsis if there are further
targets."
(lambda (&optional keymap targets prefix)
(if (null keymap)
(which-key--hide-popup-ignore-command)
(which-key--show-keymap
(if (eq (plist-get (car targets) :type) 'embark-become)
"Become"
(format "Act on %s '%s'%s"
(plist-get (car targets) :type)
(embark--truncate-target (plist-get (car targets) :target))
(if (cdr targets) "…" "")))
(if prefix
(pcase (lookup-key keymap prefix 'accept-default)
((and (pred keymapp) km) km)
(_ (key-binding prefix 'accept-default)))
keymap)
nil nil t (lambda (binding)
(not (string-suffix-p "-argument" (cdr binding))))))))
(setq embark-indicators
'(embark-which-key-indicator
embark-highlight-indicator
embark-isearch-highlight-indicator))
(defun embark-hide-which-key-indicator (fn &rest args)
"Hide the which-key indicator immediately when using the completing-read prompter."
(which-key--hide-popup-ignore-command)
(let ((embark-indicators
(remq #'embark-which-key-indicator embark-indicators)))
(apply fn args)))
(advice-add #'embark-completing-read-prompter
:around #'embark-hide-which-key-indicator)
(use-package projectile
:ensure t
:init (projectile-mode +1)
:bind ("C-c p" . projectile-command-map))
(use-package yasnippet
:config (yas-reload-all)
(use-package yasnippet-snippets)
:hook (prog-mode . yas-minor-mode))
(use-package lsp-mode
:init (setq lsp-keymap-prefix "C-c l"
lsp-eldoc-render-all nil
lsp-modeline-code-actions-mode t
lsp-enable-on-type-formatting t
lsp-enable-indentation t
lsp-enable-folding t
lsp-enable-snippet t
lsp-semantic-tokens-enable nil
lsp-lens-enable t
lsp-log-io nil
lsp-headerline-breadcrumb-icons-enable t
lsp-idle-delay 0.2)
:bind (:map lsp-mode-map
("C-c l r" . lsp-rename)
("C-c l a" . lsp-execute-code-action)
("C-c l t" . lsp-find-type-definition)
("C-c l e" . lsp-iedit-highlights))
:config (define-key lsp-mode-map (kbd "C-c l") lsp-command-map)
:commands lsp)
(use-package lsp-ui
:init (setq lsp-ui-doc-enable t
lsp-ui-sideline-show-diagnostics t
lsp-ui-doc-delay 0.2
lsp-ui-sideline-show-hover t
lsp-ui-sideline-show-code-actions t
lsp-ui-peek-show-directory t
lsp-ui-doc-show-with-cursor t
;; lsp-ui-doc-use-webkit t
lsp-completion-show-kind t
lsp-completion-show-detail t
lsp-ui-doc-show-with-mouse t)
:bind (:map lsp-ui-mode-map
([remap xref-find-definitions] . lsp-ui-peek-find-definitions)
([remap xref-find-references] . lsp-ui-peek-find-references)
("C-c l i" . lsp-ui-imenu)
("C-c l d" . lsp-ui-doc-show)))
(use-package flycheck
:config
(add-to-list 'display-buffer-alist
`(,(rx bos "*Flycheck errors*" eos)
(display-buffer-reuse-window
display-buffer-in-side-window)
(side . bottom)
(reusable-frames . visible)
(window-height . 0.33)))
:init (global-flycheck-mode))
(use-package consult
;; Replace bindings. Lazily loaded due by `use-package'.
:bind (;; C-c bindings (mode-specific-map)
("C-c h" . consult-history)
("C-c m" . consult-mode-command)
;; C-x bindings (ctl-x-map)
("C-x M-:" . consult-complex-command) ;; orig. repeat-complex-command
("C-x b" . consult-buffer) ;; orig. switch-to-buffer
("C-x 4 b" . consult-buffer-other-window) ;; orig. switch-to-buffer-other-window
("C-x 5 b" . consult-buffer-other-frame) ;; orig. switch-to-buffer-other-frame
;; Custom M-# bindings for fast register access
("M-#" . consult-register-load)
("M-'" . consult-register-store) ;; orig. abbrev-prefix-mark (unrelated)
("C-M-#" . consult-register)
;; Other custom bindings
("M-y" . consult-yank-pop) ;; orig. yank-pop
;; M-g bindings (goto-map)
("M-g f" . consult-flycheck) ;; Alternative: consult-flycheck
("M-g g" . consult-goto-line) ;; orig. goto-line
("M-g M-g" . consult-goto-line) ;; orig. goto-line
("M-g o" . consult-outline) ;; Alternative: consult-org-heading
("M-g m" . consult-mark)
("M-g k" . consult-global-mark)
("M-g i" . consult-imenu)
("M-g I" . consult-imenu-multi)
;; M-s bindings (search-map)
("M-s f" . consult-find)
("M-s F" . consult-locate)
("M-s g" . consult-grep)
("M-s G" . consult-git-grep)
("M-s r" . consult-ripgrep)
("M-s l" . consult-line)
("M-s L" . consult-line-multi)
("M-s m" . consult-multi-occur)
("M-s k" . consult-keep-lines)
("M-s u" . consult-focus-lines)
;; Isearch integration
("M-s e" . consult-isearch-history)
:map isearch-mode-map
("M-e" . consult-isearch-history) ;; orig. isearch-edit-string
("M-s e" . consult-isearch-history) ;; orig. isearch-edit-string
("M-s l" . consult-line) ;; needed by consult-line to detect isearch
("M-s L" . consult-line-multi)) ;; needed by consult-line to detect isearch
;; Enable automatic preview at point in the *Completions* buffer. This is
;; relevant when you use the default completion UI. You may want to also
;; enable `consult-preview-at-point-mode` in Embark Collect buffers.
:hook (completion-list-mode . consult-preview-at-point-mode)
;; The :init configuration is always executed (Not lazy)
:init
;; Optionally configure the register formatting. This improves the register
;; preview for `consult-register', `consult-register-load',
;; `consult-register-store' and the Emacs built-ins.
(setq register-preview-delay 0
register-preview-function #'consult-register-format)
;; Optionally tweak the register preview window.
;; This adds thin lines, sorting and hides the mode line of the window.
(advice-add #'register-preview :override #'consult-register-window)
;; Optionally replace `completing-read-multiple' with an enhanced version.
(advice-add #'completing-read-multiple :override #'consult-completing-read-multiple)
;; Use Consult to select xref locations with preview
(setq xref-show-xrefs-function #'consult-xref
xref-show-definitions-function #'consult-xref)
;; Use `consult-completion-in-region' if Vertico is enabled.
;; Otherwise use the default `completion--in-region' function.
(setq completion-in-region-function
(lambda (&rest args)
(apply (if vertico-mode
#'consult-completion-in-region
#'completion--in-region)
args)))
;; Configure other variables and modes in the :config section,
;; after lazily loading the package.
:config
;; Optionally configure preview. The default value
;; is 'any, such that any key triggers the preview.
(setq consult-preview-key (list :debounce 0.5 'any))
;; (setq consult-preview-key (kbd "M-."))
;; (setq consult-preview-key (list (kbd "<S-down>") (kbd "<S-up>")))
;; For some commands and buffer sources it is useful to configure the
;; :preview-key on a per-command basis using the `consult-customize' macro.
(consult-customize
consult-theme
:preview-key '(:debounce 0.2 any)
consult-ripgrep consult-git-grep consult-grep
consult-bookmark consult-recent-file consult-xref
consult--source-recent-file consult--source-project-recent-file consult--source-bookmark
:preview-key (kbd "M-."))
;; Preview immediately theme on M-., on up/down after 0.5s, on any other key after 1s
(consult-customize consult-theme
:preview-key
(list (kbd "M-.")
:debounce 0.5 (kbd "<up>") (kbd "<down>")
:debounce 1 'any))
;; Optionally configure the narrowing key.
;; Both < and C-+ work reasonably well.
(setq consult-narrow-key "<") ;; (kbd "C-+")
;; Optionally make narrowing help available in the minibuffer.
;; You may want to use `embark-prefix-help-command' or which-key instead.
;; (define-key consult-narrow-map (vconcat consult-narrow-key "?") #'consult-narrow-help)
;; Configure S-up/S-down preview keys
(define-key vertico-map [S-up] #'vertico-previous)
(define-key vertico-map [S-down] #'vertico-next)
(consult-customize consult-recent-file :preview-key '([S-up] [S-down]))
;; Optionally configure a function which returns the project root directory.
;; There are multiple reasonable alternatives to chose from.
;;;; 1. project.el (project-roots)
(setq consult-project-root-function
(lambda ()
(when-let (project (project-current))
(car (project-roots project)))))
;;;; 2. projectile.el (projectile-project-root)
;; (autoload 'projectile-project-root "projectile")
;; (setq consult-project-root-function #'projectile-project-root)
;;;; 3. vc.el (vc-root-dir)
;; (setq consult-project-root-function #'vc-root-dir)
;;;; 4. locate-dominating-file
;; (setq consult-project-root-function (lambda () (locate-dominating-file "." ".git")))
)
(use-package consult-flycheck
:after (flycheck consult))
(use-package consult-company
:after (company consult)
:custom (define-key company-mode-map [remap completion-at-point] #'consult-company))
(use-package consult-projectile
:after (consult projectile))
(use-package consult-yasnippet
:after (yasnippet consult))
(use-package consult-lsp
:after (consult marginalia lsp-mode)
:config (consult-lsp-marginalia-mode t))
(use-package tree-sitter
:init (use-package tree-sitter-langs)
(global-tree-sitter-mode)
:hook (tree-sitter-after-on-hook #'tree-sitter-hl-mode))
(use-package smartparens
:bind ("C-M-f" . 'sp-forward-sexp)
("C-M-b" . 'sp-backward-sexp)
:config (smartparens-global-mode)
:init (smartparens-strict-mode t))
(require 'paren)
(set-face-foreground 'show-paren-match "#FF3377")
(set-face-background 'show-paren-match (face-background 'default))
(set-face-attribute 'show-paren-match nil :weight 'extra-bold)
(show-paren-mode 1)
(use-package rainbow-delimiters
:hook (prog-mode . rainbow-delimiters-mode))
(use-package magit
:config (setq magit-ediff-dwim-show-on-hunks t))
(use-package fringe-helper
:ensure t)
(use-package git-gutter-fringe+
:config
(setq git-gutter-fr+-side 'right-fringe) ;; left side is for flycheck
(set-face-foreground 'git-gutter-fr+-modified "#e77818")
(set-face-background 'git-gutter-fr+-modified "#e77818")
(set-face-foreground 'git-gutter-fr+-deleted "#a20417")
(set-face-background 'git-gutter-fr+-deleted "#a20417")
(set-face-foreground 'git-gutter-fr+-added "#007144")
(set-face-background 'git-gutter-fr+-added "#007144")
(setq-default right-fringe-width 10)
:init (global-git-gutter+-mode))
(use-package highlight-indent-guides
:custom (highlight-indent-guides-method 'bitmap)
(highlight-indent-guides-auto-enabled t)
(highlight-indent-guides-delay 0)
(highlight-indent-guides-responsive 'stack)
:hook (prog-mode . highlight-indent-guides-mode))
(defun my-highlighter (level responsive display)
(if (> 1 level)
nil
(highlight-indent-guides--highlighter-default level responsive display)))
(setq highlight-indent-guides-highlighter-function 'my-highlighter)
(use-package expand-region
:bind ("C-c e =" . 'er/expand-region)
("C-c e p" . 'er/mark-inside-pairs)
("C-c e P" . 'er/mark-outside-pairs)
("C-c e q" . 'er/mark-inside-quotes)
("C-c e Q" . 'er/mark-outside-quotes)
("C-c e m" . 'er/mark-method-call)
("C-c e c" . 'er/mark-comment)
("C-c e -" . 'er/contract-region))
(use-package drag-stuff
:hook (prog-mode . drag-stuff-mode)
:config (drag-stuff-define-keys))
(global-auto-revert-mode t)
(save-place-mode 1)
(use-package auto-highlight-symbol
:ensure t
:custom-face (ahs-definition-face ((t (:background "dark orange" :foreground "black"))))
(ahs-face ((t (:background "orange" :foreground "black"))))
(ahs-plugin-defalt-face ((t (:background "#1E2029" :foreground "dark orange"))))
:hook (prog-mode . auto-highlight-symbol-mode))
(use-package rust-mode
:init (setq rust-format-on-save nil)
:hook (rust-mode . lsp))
(setq lsp-rust-analyzer-server-display-inlay-hints t
lsp-rust-analyzer-display-chaining-hints t
lsp-rust-analyzer-display-parameter-hints t)
(use-package elixir-mode
:hook (elixir-mode . lsp)
:init (add-to-list 'exec-path "~/.elixir_ls/"))
(use-package elixir-yasnippets)
(use-package flycheck-elixir)
(use-package haskell-mode)
(use-package lsp-haskell
:hook (haskell-mode . lsp)
(haskell-literate-mode . lsp))
(use-package toml-mode)
(use-package yaml)
(use-package dockerfile-mode)
(use-package doom-modeline
:custom
(doom-modeline-height 50)
(doom-modeline-hud t)
(doom-modeline-enable-word-count t)
:init (doom-modeline-mode 1))
(setq-default display-time-default-load-average nil)
(display-time-mode 1)
(use-package all-the-icons)
(use-package doom-themes
:config (doom-themes-org-config)
:custom
(doom-themes-enable-bold t)
(doom-themes-enable-italic t))
(use-package solaire-mode
:config (solaire-global-mode t))
(add-to-list 'solaire-mode-themes-to-face-swap "^doom-")
(load-theme 'doom-vibrant
:no-confirm)
(setq inhibit-startup-screen t)
(setq initial-scratch-message nil
inhibit-startup-echo-area-message t)
(scroll-bar-mode -1)
(menu-bar-mode -1)
(tool-bar-mode -1)
(setq-default cursor-type 'bar)
(global-hl-line-mode t)
(add-hook 'prog-mode-hook 'display-line-numbers-mode)
(fringe-mode '(15 . 10))
(add-to-list 'default-frame-alist '(font . "Monoid Nerd Font Mono-13"))
(set-face-attribute 'default t :font "Monoid Nerd Font Mono")
(global-auto-composition-mode t)
(custom-set-faces
'(font-lock-comment-face ((t (:slant italic)))))
(when window-system
(add-hook 'prog-mode-hook 'prettify-symbols-mode))
(set-face-attribute 'org-table nil :inherit 'fixed-pitch)
(setq org-startup-indented t
org-ellipsis " "
org-pretty-entities t
org-hide-emphasis-markers t
org-fontify-whole-heading-line t
org-fontify-done-headline t
org-hide-emphasis-markers t
org-edit-src-content-indentation 0
org-src-tab-acts-natively t
org-src-fontify-natively t
org-src-preserve-indentation t
org-support-shift-select 'always
org-edit-src-persistent-message nil
org-fontify-quote-and-verse-blocks t)
(font-lock-add-keywords 'org-mode
'(("^ *\\([-]\\) "
(0 (prog1 () (compose-region (match-beginning 1) (match-end 1) "•"))))))
(custom-theme-set-faces
'user
'(org-code ((t (:inherit (shadow fixed-pitch)))))
'(org-indent ((t (:inherit (org-hide fixed-pitch))))))
(use-package org-bullets
:hook (org-mode . org-bullets-mode)
:init (org-bullets-mode 1))
(setq initial-major-mode 'org-mode)
(defface org-checkbox-done-text
'((t (:foreground "#71696A" :strike-through t)))
"Face for the text part of a checked org-mode checkbox.")
(font-lock-add-keywords
'org-mode
`(("^[ \t]*\\(?:[-+*]\\|[0-9]+[).]\\)[ \t]+\\(\\(?:\\[@\\(?:start:\\)?[0-9]+\\][ \t]*\\)?\\[\\(?:X\\|\\([0-9]+\\)/\\2\\)\\][^\n]*\n\\)"
1 'org-checkbox-done-text prepend))
'append)
(global-set-key (kbd "C-+") #'text-scale-increase)
(global-set-key (kbd "C--") #'text-scale-decrease)
(global-set-key (kbd "C-x k") 'kill-this-buffer)
(defalias 'yes-or-no-p 'y-or-n-p)
(setq-default indent-tabs-mode nil)
(setq-default tab-width 4)
(defun consoli/infer-indentation-style ()
"If our source file use tabs, we use tabs, if spaces, spaces.
And if neither, we use the current indent-tabs-mode"
(let ((space-count (how-many "^ " (point-min) (point-max)))
(tab-count (how-many "^\t" (point-min) (point-max))))
(if (> space-count tab-count) (setq indent-tabs-mode nil))
(if (> tab-count space-count) (setq indent-tabs-mode t))))
;; (add-hook 'prog-mode-hook #'consoli/infer-indentation-style)
(global-unset-key (kbd "C-z"))
(pending-delete-mode t)
(delete-selection-mode t)
(use-package good-scroll
:custom (redisplay-dont-pause 1)
:config (good-scroll-mode 1))
(setq scroll-preserve-screen-position t
scroll-conservatively 101)
(setq make-backup-files nil)
(setq auto-save-default nil)
(global-set-key (kbd "M-u") 'upcase-dwim)
(global-set-key (kbd "M-l") 'downcase-dwim)
(global-set-key (kbd "M-c") 'capitalize-dwim)
(use-package crux
:bind ([remap kill-line] . crux-smart-kill-line)
([remap kill-whole-line] . crux-kill-whole-line)
("C-c n" . crux-cleanup-buffer-or-region)
("C-c d" . crux-duplicate-current-line-or-region)
("C-c M-d" . crux-duplicate-and-comment-current-line-or-region))
(use-package exec-path-from-shell
:init (exec-path-from-shell-initialize))
(defun smarter-beginning-of-line (arg)
"Move point back to indentation of beginning of line.
Move point to the first non-whitespace character on this line.
If point is already there, move to the beginning of the line.
Effectively toggle between the first non-whitespace character and the beginning of the line.
If ARG is not nil or 1, move forward ARG - 1 lines first. If point reaches the beginning or end of the buffer, stop there."
(interactive "^p")
(setq arg (or arg 1))
(when (/= arg 1)
(let ((line-move-visual nil))
(forward-line (1- arg))))
(let ((orig-point (point)))
(back-to-indentation)
(when (= orig-point (point))
(move-beginning-of-line 1))))
(global-set-key [remap move-beginning-of-line] 'smarter-beginning-of-line)
(defun consoli/smart-newline ()
"Add two newlines and put the cursor at the right indentation
between them if a newline is attempted when the cursor is between
two curly braces, otherwise do a regular newline and indent"
(interactive)
(if (or
(and (equal (char-before) 123) ; {
(equal (char-after) 125)) ; }
(and (equal (char-before) 40) ; (
(equal (char-after) 41))) ; )
(progn (newline-and-indent)
(split-line)
(indent-for-tab-command))
(newline-and-indent)))
(global-set-key (kbd "RET") 'consoli/smart-newline)
(defun consoli/insert-new-line-bellow ()
(interactive)
(let ((current-point (point)))
(move-end-of-line 1)
(open-line 1)
(goto-char current-point)))
(global-set-key (kbd "C-S-<down>") 'consoli/insert-new-line-bellow)
(defun consoli/insert-new-line-above ()
(interactive)
(let ((current-point (point)))
(move-beginning-of-line 1)
(newline-and-indent)
(indent-according-to-mode)
(goto-char current-point)
(forward-char)))
(global-set-key (kbd "C-S-<up>") 'consoli/insert-new-line-above)
(set-frame-parameter (selected-frame) 'buffer-predicate #'buffer-file-name)