Contains all the configuration of emacs out of the box, no packages installed in here
Set up melpa and use package to make things easier https://cestlaz.github.io/posts/using-emacs-1-setup/
(require 'package)
(setq package-archives
'(("gnu" . "https://elpa.gnu.org/packages/")
("melpa-stb" . "https://stable.melpa.org/packages/")
("melpa" . "https://melpa.org/packages/"))
tls-checktrust t
tls-program '("gnutls-cli --x509cafile %t -p %p %h")
gnutls-verify-error t)
(package-refresh-contents)
(when (not package-archive-contents)
(package-refresh-contents))
(require 'org)
;; Bootstrap `use-package'
(unless (require 'use-package nil t)
(if (not (yes-or-no-p (concat "Refresh packages, install use-package and"
" other packages used by init file? ")))
(error "you need to install use-package first")
(package-install 'use-package)
(require 'use-package)
))
(setq use-package-always-ensure t)
Modes that are not in melpa and you found on the internet. Put them into the lisp folder.
(add-to-list 'load-path "~/.emacs.d/lisp/")
- Menu
- Toolbar
- Scroolbar
- Splash-Screen
(menu-bar-mode -1)
(tool-bar-mode -1)
(scroll-bar-mode -1)
(setq inhibit-splash-screen t)
(setq inhibit-startup-message t)
Activate some UI built-in features
- Line Numbers
- Column Line
- Parentesis
- Size of Current File
(global-display-line-numbers-mode 1)
(setq column-number-mode t)
(show-paren-mode 1)
(size-indication-mode 1)
Set frame title to a short version of it.
(setq frame-title-format
'((:eval (if (buffer-file-name)
(abbreviate-file-name (buffer-file-name))
"%b"))))
Set a better default when the buffers goes in conflicts for some reason
(require 'uniquify)
(setq uniquify-buffer-name-style 'forward)
(setq uniquify-separator "/")
;; rename after killing uniquified
(setq uniquify-after-kill-buffer-p t)
;; don't muck with special buffers
(setq uniquify-ignore-buffers-re "^\\*")
Note: forced to put this here for theme dependecy reasons!!! Highlight the word you are on in case you stop there for some time
(use-package idle-highlight-mode
:diminish idle-highlight-mode
:config
(add-hook 'prog-mode-hook 'idle-highlight-mode)
)
Minimalistic theme setup.
;; <Color theme initialization code>
(setq current-theme nil)
(defun benkio-dark-theme ()
"Load Simple Dark Benkio Theme"
(interactive)
(set-foreground-color "white")
(set-background-color "grey15")
(set-face-attribute 'region nil :background "SlateBlue4")
(set-face-attribute 'line-number-current-line nil :background "SlateBlue4")
(set-face-attribute 'idle-highlight nil :background "DarkOrange3")
(set-face-attribute 'mode-line nil :background "PaleGreen")
(setq current-theme '(benkio-dark-theme))
)
(defun benkio-light-theme ()
"Load Simple Light Benkio Theme"
(interactive)
(set-foreground-color "black")
(set-background-color "old lace")
(set-face-attribute 'region nil :background "LightSkyBlue1")
(set-face-attribute 'line-number-current-line nil :background "LightSkyBlue1")
(set-face-attribute 'idle-highlight nil :background "plum1")
(set-face-attribute 'mode-line nil :background "PaleGreen")
(setq current-theme '(benkio-light-theme))
)
(defun synchronize-theme ()
(setq hour
(string-to-number
(substring (current-time-string) 11 13)))
(if (member hour (number-sequence 6 16))
(setq now '(benkio-light-theme))
(setq now '(benkio-dark-theme)))
(if (equal now current-theme)
nil
(setq current-theme now)
(eval now) ) )
(run-with-timer 0 3600 'synchronize-theme)
(add-hook 'after-make-frame-functions
(lambda (frame)
(select-frame frame)
(when (display-graphic-p frame)
(synchronize-theme)
(eval current-theme))))
Based on the width of the frame it changes the size of the font. It could be called after the startup as well.
(defun set-font-height-on-frame-width (&optional frame ratio)
"Set font based on the frame size. The page in full screen should show 50 lines"
(interactive (list
(selected-frame)
(read-number "Ratio (140, less bigger, more smaller):" 140)
)
)
(let* ((frameWidth (frame-outer-width frame))
;; Perfect ratio is 1400 / 10. We need an adjustment (feedback) for the other display
;; Based on the distance from 1400
(zeroAdjustment (/ (- frameWidth (* ratio 10)) 2))
(heightComputed (+ (/ frameWidth 10) zeroAdjustment))
(height (if (< heightComputed 0) ratio heightComputed))
)
(message "Set font based on the frame size(divided by 10): %d height: %d" frameWidth height) ;Adding this will make it run at startup, weird
(set-face-attribute 'default nil :height height)
)
)
(add-hook 'after-make-frame-functions 'set-font-height-on-frame-width)
(add-hook 'window-setup-hook 'set-font-height-on-frame-width)
- Backup files
- Autosave and beckup files
- Blinking cursor
- Ringing Bell
- Using Tabs
- Windows keys
- Truncate-lines for minibuffer
- Truncate-lines for Calendar
- Upcase region warning
- popup confirmation windows
(setq make-backup-files nil)
(setq auto-save-default nil)
(blink-cursor-mode -1)
(setq ring-bell-function 'ignore)
(setq-default indent-tabs-mode nil)
(when (eq system-type 'windows-nt)
(setq w32-pass-lwindow-to-system nil)
(setq w32-lwindow-modifier 'super) ; Left Windows key
(setq w32-pass-rwindow-to-system nil)
(setq w32-rwindow-modifier 'super) ; Right Windows key
(setq w32-pass-apps-to-system nil)
(setq w32-apps-modifier 'hyper)) ; Menu/App key
(add-hook 'minibuffer-setup-hook
(lambda () (setq truncate-lines nil)))
(add-hook 'calendar-initial-window-hook
(lambda () (setq truncate-lines nil)))
(put 'upcase-region 'disabled nil)
(setq use-dialog-box nil)
- y/n for yes and no
- Save cursor position
- Electric parentesis
- Auto-revert-mode
- Visual Line mode
- UTF-8
- Allow narrow-to-region to be used without confirmation
- Recursive minibuffer change
- Recent-f mode
- Warn when opening files bigger than 100MB
- Better Scrolling
- Winner Mode: restore windows, especially for ediff sessions
- Save on frame focus out: https://emacsredux.com/blog/2014/03/22/a-peek-at-emacs-24-dot-4-focus-hooks/
- hs-minor-mode when coding
- Dired hide details by default
term-line-mode
onansi-term
to enable normalC-x
,M-x
and editingorg-agenda
task filesorg-capture
default file and templateabbrev-mode
always on- Save abbrev silently
- Automatically add final newline on file save and visiting
- When you delete files they got into the thrash instead of permanently deleted
(defalias 'yes-or-no-p 'y-or-n-p)
(savehist-mode 1)
(electric-pair-mode 1)
(global-auto-revert-mode 1)
(global-visual-line-mode 1)
(set-language-environment "UTF-8")
(prefer-coding-system 'utf-8)
(set-default-coding-systems 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(put 'narrow-to-region 'disabled nil)
(setq enable-recursive-minibuffers t)
(recentf-mode 1)
(setq large-file-warning-threshold 100000000)
(setq scroll-margin 0
scroll-conservatively 100000
scroll-preserve-screen-position 1)
(winner-mode)
(add-hook 'focus-out-hook (lambda () (save-some-buffers t)))
(defadvice select-window (after select-window-and-do-stuff activate) (save-some-buffers t))
(add-hook 'prog-mode-hook #'hs-minor-mode)
(add-hook 'dired-mode-hook
(lambda ()
(dired-hide-details-mode)))
(defadvice ansi-term (after advice-term-line-mode activate) (term-line-mode))
(setq org-agenda-files '("~/Dropbox/notes/TODO.org"))
(setq org-default-notes-file (concat org-directory "~/Dropbox/notes/TODO.org"))
(setq org-capture-templates
'(("t" "Todo" entry (file+headline "~/Dropbox/notes/TODO.org" "TODOs")
"* TODO %?\n %i\n %a")
("d" "Download" entry (file+headline "~/Dropbox/notes/TODO.org" "Download")
"* %?\n %i\n %a")
("g" "Gigs" entry (file+headline "~/Dropbox/notes/TODO.org" "Gigs")
"* %?\n %i\n %a")
))
(setq-default abbrev-mode t)
(setq save-abbrevs 'silently)
(setq require-final-newline 'visit-save)
(setq delete-by-moving-to-trash t)
- Recent-f save list every 5 minutes
- Emacs window fullscreen at startup
- Recent-f list to higher maximum size
- Always load newest byte code first
- Reduce the frequency of garbage collection by making it happen on each 50MB of allocated data (the default is on every 0.76MB)
- Smart Tab Behaviour
- Path executable on windows (git, 7z, curl…)
- Winner-undo after ediff quits, hook
- Set ediff options:
- Remove separate frame
- Split vertical
- Ignore whitespaces
- Bash shell path (NixOs - darwin-nix)
- Add more parens to the list of available
(add-to-list 'default-frame-alist '(fullscreen . maximized))
(run-at-time nil (* 5 60) 'recentf-save-list)
(setq recentf-max-saved-items 50)
(setq load-prefer-newer t)
(setq gc-cons-threshold 50000000)
(setq tab-always-indent 'complete)
(when (eq system-type 'windows-nt)
(add-to-list 'exec-path "C:/Program Files/Git/bin")
(add-to-list 'exec-path "C:/Program Files/Git/mingw64/bin")
(setenv "PATH" (concat "C:/Program Files/Git/bin;" "C:/Program Files/Git/mingw64/bin;" (getenv "PATH")))
;; needed for arc-mode
(add-to-list 'exec-path "C:/Program Files/7-Zip"))
(defun exit-ediff-hook ()
(kill-buffer "*Ediff Registry*")
(winner-undo)
)
(add-hook 'ediff-after-quit-hook-internal 'exit-ediff-hook)
(setq ediff-window-setup-function 'ediff-setup-windows-plain)
(setq ediff-split-window-function 'split-window-horizontally)
(setq ediff-diff-options "-w")
(setq explicit-shell-file-name "/run/current-system/sw/bin/bash")
;; make electric-pair-mode work on more brackets
(setq electric-pair-pairs
'(
(?\" . ?\")
(?\` . ?\`)
(?\{ . ?\})))
(defvar org-electric-pairs '(
(?/ . ?/)
(?_ . ?_)
(?~ . ?~)
(?+ . ?+)
(?= . ?=)) "Electric pairs for org-mode.")
(defun org-add-electric-pairs ()
(setq-local electric-pair-pairs (append electric-pair-pairs org-electric-pairs))
(setq-local electric-pair-text-pairs electric-pair-pairs))
(add-hook 'org-mode-hook 'org-add-electric-pairs)
Set fonts based of the content of the font
folder
Add the support of the emoji, based on Xah Lee code.
;; Emacs: Font Setup http://ergoemacs.org/emacs/emacs_list_and_set_font.html
;; set default font
(set-frame-font
(cond
((member "ProggyClean Nerd Font Mono" (font-family-list)) "ProggyClean Nerd Font Mono")
((member "JetBrainsMono Nerd Font Mono" (font-family-list)) "JetBrainsMono Nerd Font Mono")
((member "DejaVu Sans Mono" (font-family-list)) "DejaVu Sans Mono")
((member "Inconsolata" (font-family-list)) "Inconsolata")
((member "Noto Mono" (font-family-list)) "Noto Mono")
((member "Consolas" (font-family-list)) "Consolas-12")
((member "Menlo" (font-family-list)) "Menlo-16"))
;; (cond
;; ((string-equal system-type "windows-nt")
;; (if (member "Consolas" (font-family-list)) "Consolas-12" nil ))
;; ((string-equal system-type "darwin")
;; (if (member "Menlo" (font-family-list)) "Menlo-16" nil ))
;; ((string-equal system-type "gnu/linux")
;; (if (member "DejaVu Sans Mono" (font-family-list)) "DejaVu Sans Mono" nil ))
;; (t nil))
t t)
;; set font for emoji
(set-fontset-font
t
'(#x1f300 . #x1fad0)
(cond
((member "Noto Color Emoji" (font-family-list)) "Noto Color Emoji")
((member "Noto Emoji" (font-family-list)) "Noto Emoji")
((member "Segoe UI Emoji" (font-family-list)) "Segoe UI Emoji")
((member "Symbola" (font-family-list)) "Symbola")
((member "Apple Color Emoji" (font-family-list)) "Apple Color Emoji"))
;; Apple Color Emoji should be before Symbola, but Richard Stallman skum disabled it.
;; GNU Emacs Removes Color Emoji Support on the Mac
;; http://ergoemacs.org/misc/emacs_macos_emoji.html
;;
)
;; set font for symbols
(set-fontset-font
t
'symbol
(cond
((string-equal system-type "windows-nt")
(cond
((member "Segoe UI Symbol" (font-family-list)) "Segoe UI Symbol")))
((string-equal system-type "darwin")
(cond
((member "Apple Symbols" (font-family-list)) "Apple Symbols")))
((string-equal system-type "gnu/linux")
(cond
((member "Symbola" (font-family-list)) "Symbola")))))
Ensure the PATH variable is in scope for emacs to use
(use-package exec-path-from-shell
:if (memq window-system '(mac ns x))
:config
(exec-path-from-shell-initialize))
http://xahlee.info/emacs/emacs/emacs_icomplete_mode.html
Set up IComplete
and fido
for completion on the minibuffer
(if (version< emacs-version "28.1")
(progn
(progn
;; make buffer switch command do suggestions, also for find-file command
(require 'ido)
(ido-mode 1)
;; show choices vertically
(setf (nth 2 ido-decorations) "\n")
;; show any name that has the chars you typed
(setq ido-enable-flex-matching t)
;; use current pane for newly opened file
(setq ido-default-file-method 'selected-window)
;; use current pane for newly switched buffer
(setq ido-default-buffer-method 'selected-window)
)
(progn
;; minibuffer enhanced completion icomplete
(require 'icomplete)
(icomplete-mode 1)
;; show choices vertically
(setq icomplete-separator "\n")
(setq icomplete-hide-common-prefix nil)
(setq icomplete-in-buffer t)
(define-key icomplete-minibuffer-map (kbd "<right>") 'icomplete-forward-completions)
(define-key icomplete-minibuffer-map (kbd "<left>") 'icomplete-backward-completions)))
(fido-vertical-mode 1))
Save your files every time you change the window https://github.com/bbatsov/super-save
(use-package super-save
:config
(super-save-mode +1))
Allow to visually go back and forth between undo history
(use-package undo-tree
:config (global-undo-tree-mode)
(setq undo-tree-auto-save-history nil)
)
Give you suggestions about the keybindings
(use-package which-key
:config
(which-key-mode))
Editing mulitiple occurrences of the same highlighted word at once.
(use-package iedit)
turn grep buffers writable
(use-package wgrep)
Automatically signal and clean whitespaces
(use-package whitespace
:init
(dolist (hook '(prog-mode-hook text-mode-hook))
(add-hook hook #'whitespace-mode))
:config
(progn
;; Make whitespace-mode with very basic background coloring for whitespaces.
;; http://ergoemacs.org/emacs/whitespace-mode.html
(setq whitespace-style (quote (face tabs newline tab-mark newline-mark empty trailing)))
;; Make whitespace-mode and whitespace-newline-mode use “¶” for end of line char and “▷” for tab.
(setq whitespace-display-mappings
;; all numbers are unicode codepoint in decimal. e.g. (insert-char 182 1)
'(
(space-mark 32 [183] [46]) ; SPACE 32 「 」, 183 MIDDLE DOT 「·」, 46 FULL STOP 「.」
(newline-mark 10 [182 10]) ; LINE FEED,
(tab-mark 9 [9655 9] [92 9]) ; tab
)))
)
https://github.com/bbatsov/crux
package containing a lot of useful functions. So you don’t need to copy and paste them from Emacs Redux
(use-package crux)
Select by region, back and forth
(use-package expand-region)
Package to cycle and change between different cases: camel, underscore, lower…
(use-package string-inflection)
https://github.com/emacsfodder/move-text Improvement on moving single line or region up and down
(use-package move-text
:config (move-text-default-bindings)
:ensure t
)
Fast search, grep alternative
(use-package rg)
Allow you to search the thing under cursor on google
(use-package google-this)
To move between windows
(use-package windmove)
library that will manage the window size in order to have the window on focus useable and the other windows shrinked but readable
(use-package golden-ratio
:config
(require 'golden-ratio)
(golden-ratio-mode 1)
(setq golden-ratio-auto-scale t))
Better visualization of open buffers
(use-package ibuffer)
This minor mode allows you to toggle a window’s “dedicated” flag. When a window is “dedicated”, Emacs will not select files into that window. This can be quite handy since many commands will use another window to show results (e.g., compilation mode, starting info, etc.) A dedicated window won’t be used for such a purpose.
Dedicated buffers will have “D” shown in the mode line.
(use-package dedicated)
Allow to visualize the kill ring in another buffer and choose what to insert at point
(use-package browse-kill-ring
:config (browse-kill-ring-default-keybindings))
Converts org file to github markdown with the command: `M-x org-gfm-export-to-markdown`
(use-package ox-gfm
:defer t
:config
(require 'ox-gfm nil t))
Slide generation from org
(use-package ox-reveal
:defer t
:config
(require 'ox-reveal)
(setq org-reveal-root "https://cdn.jsdelivr.net/npm/[email protected]")
(setq org-reveal-mathjax t))
(use-package htmlize)
(use-package ox-twbs)
(use-package ox-jira)
Prettify org
(use-package org-modern
:config
(with-eval-after-load 'org (global-org-modern-mode))
)
For some reason the cursor doesn’t show in org-calendar. With this code it should Reference: https://emacs.stackexchange.com/questions/78420/use-keyboard-in-org-calendar
(defun my-func (orig-fun &rest args)
(when (equal (car args) '(setq cursor-type nil))
(setcar args '(setq cursor-type 'box)))
(apply orig-fun args))
(advice-add 'org-eval-in-calendar :around #'my-func)
Auto completion framework
(use-package company
:config
(setq company-idle-delay 0)
(setq company-minimum-prefix-length 3)
(setq company-dabbrev-downcase nil)
(global-company-mode t))
Package that will format your code based on extenal programs and the mode/language you are in
(use-package format-all
:commands format-all-mode
:config
(setq-default format-all-formatters '(
("Haskell" fourmolu)
("Scala" scalafmt)
))
;; Workaround till next release to recognize treesitter mode
(add-to-list 'language-id--definitions '("Scala" scala-mode scala-ts-mode))
)
Add treesit for tree sitter support
(require 'treesit)
(setq treesit-font-lock-level 4) ;; https://github.com/KaranAhlawat/scala-ts-mode/issues/12
(setq treesit-language-source-alist
'((bash . ("https://github.com/tree-sitter/tree-sitter-bash"))
(c . ("https://github.com/tree-sitter/tree-sitter-c"))
(cpp . ("https://github.com/tree-sitter/tree-sitter-cpp"))
(css . ("https://github.com/tree-sitter/tree-sitter-css"))
(go . ("https://github.com/tree-sitter/tree-sitter-go"))
(html . ("https://github.com/tree-sitter/tree-sitter-html"))
(javascript . ("https://github.com/tree-sitter/tree-sitter-javascript"))
(json . ("https://github.com/tree-sitter/tree-sitter-json"))
(lua . ("https://github.com/Azganoth/tree-sitter-lua"))
(make . ("https://github.com/alemuller/tree-sitter-make"))
(ocaml . ("https://github.com/tree-sitter/tree-sitter-ocaml" "ocaml/src" "ocaml"))
(python . ("https://github.com/tree-sitter/tree-sitter-python"))
(php . ("https://github.com/tree-sitter/tree-sitter-php"))
(typescript "https://github.com/tree-sitter/tree-sitter-typescript" "master" "typescript/src")
(tsx "https://github.com/tree-sitter/tree-sitter-typescript" "master" "tsx/src")
(ruby . ("https://github.com/tree-sitter/tree-sitter-ruby"))
(rust . ("https://github.com/tree-sitter/tree-sitter-rust"))
(sql . ("https://github.com/m-novikov/tree-sitter-sql"))
(toml . ("https://github.com/tree-sitter/tree-sitter-toml"))
(yaml . ("https://github.com/ikatyang/tree-sitter-yaml"))
(zig . ("https://github.com/GrayJack/tree-sitter-zig"))))
(defun nf/treesit-install-all-languages ()
"Install all languages specified by `treesit-language-source-alist'."
(interactive)
(let ((languages (mapcar 'car treesit-language-source-alist)))
(dolist (lang languages)
(treesit-install-language-grammar lang)
(message "`%s' parser was installed." lang)
(sit-for 0.75))))
(use-package gnu-apl-mode)
Mode to handle CSV files
(use-package csv-mode)
Support for editor config. So the formatting rules are shared between developers.
(use-package editorconfig
:config
(editorconfig-mode 1))
(use-package s)
(use-package elm-mode)
Managing git repos
(use-package magit
:config
(setq git-commit-summary-max-length 160)
(defun set-commit-fill-column ()
(setq fill-column 160)) ;; I want longer lines
(add-hook 'git-commit-mode-hook 'set-commit-fill-column)
)
(use-package git-link ) ;; Get git links to remote
(defun kill-magit-extra-buffer-in-current-repo (&rest _)
"Delete the magit-diff buffer related to the current repo"
(let (
(magit-diff-buffer-in-current-repo (magit-get-mode-buffer 'magit-diff-mode))
(magit-process-buffer-in-current-repo (magit-get-mode-buffer 'magit-process-mode))
(kill-buffer-query-functions nil)
)
(kill-buffer magit-diff-buffer-in-current-repo)
(kill-buffer magit-process-buffer-in-current-repo)
)
)
;;
;; When compliting the magit commit,
;; delete the magit-diff buffer related to the current repo.
;;
(add-hook 'git-commit-setup-hook
(lambda ()
(add-hook 'with-editor-post-finish-hook
#'kill-magit-extra-buffer-in-current-repo
nil t))) ; the t is important
Add graphql-mode
(use-package graphql-mode)
(use-package company-ghci)
(use-package haskell-mode
:mode ("\\.purs$" "\\.hs$") ;;enable the mode for purescript as well
:config
(defun custom-haskell-mode-hook ()
"Hook for `haskell-mode'"
(set (make-local-variable 'company-backends)
'((company-capf company-dabbrev-code company-yasnippet company-files company-ghci)))
(interactive-haskell-mode)
(haskell-doc-mode)
)
(add-hook 'haskell-mode-hook 'custom-haskell-mode-hook)
)
Used to highlight different indentation levels. Useful in languages like ML, haskell, elm, scala 3..
(use-package indent-guide
:config (indent-guide-global-mode))
(add-to-list 'auto-mode-alist '("\\.json\\'" . json-ts-mode))
(add-to-list 'auto-mode-alist '("\\.ts\\'" . typescript-ts-mode))
(use-package tex
:defer t
:ensure auctex
:config
(setq TeX-auto-save t)
(setq TeX-parse-self t)
(setq-default TeX-master nil)
(add-hook 'LaTeX-mode-hook 'visual-line-mode)
(add-hook 'LaTeX-mode-hook 'flyspell-mode)
(add-hook 'LaTeX-mode-hook 'LaTeX-math-mode)
(add-hook 'LaTeX-mode-hook 'TeX-source-correlate-mode)
(add-hook 'LaTeX-mode-hook 'yas-minor-mode)
(add-hook 'LaTeX-mode-hook 'turn-on-reftex)
(setq reftex-plug-into-AUCTeX t)
(setq TeX-PDF-mode t)
(setq TeX-output-view-style
(quote
(("^pdf$" "." "evince -f %o")))))
(unless (boundp 'org-export-latex-classes)
(setq org-export-latex-classes nil))
;; Org xelatex
;; 'djcb-org-article' for export org documents to the LaTex 'article', using
;; XeTeX and some fancy fonts; requires XeTeX (see org-latex-to-pdf-process)
(add-to-list 'org-export-latex-classes
'("xebeamer"
"\\documentclass[11pt]{beamer}
\\usepackage[T1]{fontenc}
\\usepackage{fontspec}
\\usepackage{graphicx}
\\usepackage{geometry}
\\geometry{a4paper, textwidth=6.5in, textheight=10in,
marginparsep=7pt, marginparwidth=.6in}
\\usetheme{{{{beamertheme}}}}\n
\\usecolortheme{{{{beamercolortheme}}}}\n
\\beamertemplateballitem\n
\\setbeameroption{show notes}
\\usepackage[utf8]{inputenc}\n
\\usepackage[T1]{fontenc}\n
\\usepackage{hyperref}\n
\\usepackage{color}
\\usepackage{listings}
\\lstset{numbers=none,language=[ISO]C++,tabsize=4,
frame=single,
basicstyle=\\small,
showspaces=false,showstringspaces=false,
showtabs=false,
keywordstyle=\\color{blue}\\bfseries,
commentstyle=\\color{red},
}\n
\\usepackage{verbatim}\n
\\institute{{{{beamerinstitute}}}}\n
\\subject{{{{beamersubject}}}}\n"
("\\section{%s}" . "\\section*{%s}")
("\\begin{frame}[fragile]\\frametitle{%s}"
"\\end{frame}"
"\\begin{frame}[fragile]\\frametitle{%s}"
"\\end{frame}")))
;; allow for export=>beamer
;; #+LaTeX_CLASS: beamer in org files
(add-to-list 'org-export-latex-classes
;; beamer class, for presentations
'("beamer"
"\\documentclass[11pt]{beamer}\n
\\mode<{{{beamermode}}}>\n
\\usetheme{{{{beamertheme}}}}\n
\\usecolortheme{{{{beamercolortheme}}}}\n
\\beamertemplateballitem\n
\\setbeameroption{show notes}
\\usepackage[utf8]{inputenc}\n
\\usepackage[T1]{fontenc}\n
\\usepackage{hyperref}\n
\\usepackage{color}
\\usepackage{listings}
\\lstset{numbers=none,language=[ISO]C++,tabsize=4,
frame=single,
basicstyle=\\small,
showspaces=false,showstringspaces=false,
showtabs=false,
keywordstyle=\\color{blue}\\bfseries,
commentstyle=\\color{red},
}\n
\\usepackage{verbatim}\n
\\institute{{{{beamerinstitute}}}}\n
\\subject{{{{beamersubject}}}}\n"
("\\section{%s}" . "\\section*{%s}")
("\\begin{frame}[fragile]\\frametitle{%s}"
"\\end{frame}"
"\\begin{frame}[fragile]\\frametitle{%s}"
"\\end{frame}")))
;; letter class, for formal letters
(add-to-list 'org-export-latex-classes
'("letter"
"\\documentclass[11pt]{letter}\n
\\usepackage[utf8]{inputenc}\n
\\usepackage[T1]{fontenc}\n
\\usepackage{color}"
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
("\\paragraph{%s}" . "\\paragraph*{%s}")
("\\subparagraph{%s}" . "\\subparagraph*{%s}")))
;; Uses xelatex, just in case I want to have fancy fonts
(setq org-latex-pdf-process
'("xelatex -interaction nonstopmode %f"))
(use-package markdown-mode
:mode (("\\.md\\'" . gfm-mode)
("\\.markdown\\'" . gfm-mode))
:config
(setq markdown-fontify-code-blocks-natively t)
:preface
(defun jekyll-insert-image-url ()
(interactive)
(let* ((files (directory-files "../assets/images"))
(selected-file (completing-read "Select image: " files nil t)))
(insert (format "![%s](/assets/images/%s)" selected-file selected-file))))
(defun jekyll-insert-post-url ()
(interactive)
(let* ((files (remove "." (mapcar #'file-name-sans-extension (directory-files "."))))
(selected-file (completing-read "Select article: " files nil t)))
(insert (format "{%% post_url %s %%}" selected-file)))))
(use-package markdown-toc)
(use-package nix-mode
:mode "\\.nix\\'")
Emacs Rest Client
(use-package restclient
:config (add-to-list 'auto-mode-alist '("\\.http\\'" . restclient-mode))
)
Add all the needed components for scala:
- scala mode
- sbt mode
;; ;; Enable scala-mode and sbt-mode
;; (use-package scala-mode
;; :mode "\\.s\\(cala\\|bt\\|c\\)$"
;; :config (add-hook 'scala-mode-hook 'hs-minor-mode)
;; )
(use-package scala-ts-mode)
(add-to-list 'treesit-language-source-alist '(scala "https://github.com/tree-sitter/tree-sitter-scala"))
(use-package sbt-mode
:commands sbt-start sbt-command
:config
;; WORKAROUND: https://github.com/ensime/emacs-sbt-mode/issues/31
;; allows using SPACE when in the minibuffer
(substitute-key-definition
'minibuffer-complete-word
'self-insert-command
minibuffer-local-completion-map)
;; sbt-supershell kills sbt-mode: https://github.com/hvesalai/emacs-sbt-mode/issues/152
(setq sbt:program-options '("-Dsbt.supershell=false"))
)
(use-package smithy-mode)
(use-package lorem-ipsum)
(use-package simple-httpd)
snippets for coding and more
; Collection of snippets
(use-package yasnippet-snippets
:defer t
:config (add-to-list 'load-path
"~/.emacs.d/plugins/yasnippet"))
(use-package yasnippet
:diminish yas-minor-mode
:defer t
:config
(add-to-list 'load-path
"~/.emacs.d/snippets"))
(yas-global-mode 1)
File system for emacs
(use-package dired
:ensure nil
:config
;; dired - reuse current buffer by pressing 'a'
(put 'dired-find-alternate-file 'disabled nil)
;; always delete and copy recursively
(setq dired-recursive-deletes 'always)
(setq dired-recursive-copies 'always)
;; if there is a dired buffer displayed in the next window, use its
;; current subdir, instead of the current subdir of this dired buffer
(setq dired-dwim-target t)
(setq dired-listing-switches "-alh")
(require 'dired-x))
A substitute of Ispell that works on Windows as well. Tool for spellchecking Following these instructions: https://lists.gnu.org/archive/html/help-gnu-emacs/2014-04/msg00030.html
(cond
((string-equal system-type "windows-nt")
(progn
;; Add executable
(add-to-list 'exec-path "~/.emacs.d/hunspell/bin/")
;; Set dictionary
(setq ispell-program-name (locate-file "hunspell"
exec-path exec-suffixes 'file-executable-p))
))
(t (setq ispell-program-name "~/.nix-profile/bin/aspell"))
)
(require 'ispell)
Allow you to search and do stuff for youtube videos, using the insidious api
(use-package ytdious)
Modes not on Melpa/Elpa. Imported from local folder
Functions used throughout the elisp code to generate other functionalities
(defun command-exists-p (command)
"check if the given input command actually exists"
(setq commandExist nil)
(condition-case nil
(progn
(call-process command nil 0)
(setq commandExist t)
)
(error nil)
)
commandExist
)
(defun files-from-dired-current-directory ()
"Ask the user for a list of files from the current directory showing the files in dired"
(setq
files (if (not (null (dired-get-marked-files)))
(dired-get-marked-files)
(list (read-file-name "The initial file name: ")))
)
(message "%s" files)
(while (yes-or-no-p "Another file? ")
(progn
(setq files (append files (list (read-file-name "Next file name: "))))
)
)
files
)
unctions for alignment of text and indentation of buffer
(defun indent-buffer-or-region ()
"indent whole buffer"
(interactive)
(delete-trailing-whitespace)
(setq regionStart (point-min)
regionEnd (point-max))
(when (use-region-p)
(setq regionStart (region-beginning)
regionEnd (region-end)))
(save-excursion (indent-region regionStart regionEnd nil))
(untabify regionStart regionEnd))
Collect all the functions that move the cursor somewhere
(defun goto-column (column)
(interactive "nColumn: ")
(move-to-column column t))
(defun switch-to-existing-buffer-other-window (part)
"Switch to buffer with PART in its name."
(interactive
(list (read-buffer-to-switch "Switch to buffer in other window: ")))
(let ((candidates
(cl-remove
nil
(mapcar (lambda (buf)
(let ((pos (string-match part (buffer-name buf))))
(when pos
(cons pos buf))))
(buffer-list)))))
(unless candidates
(user-error "There is no buffers with %S in its name." part))
(setq candidates (cl-sort candidates #'< :key 'car))
(switch-to-buffer-other-window (cdr (car candidates)))))
Functions over buffers
(defun kill-all-buffers ()
(interactive)
(mapcar 'kill-buffer (buffer-list))
(delete-other-windows))
Here you can find the functions to instruct ffmpeg. Very useful when you have to cut a specific video, extract audio, convert to a specific format.
(defun timeToSeconds (time)
"get as input the time in format 00:00:00 and return the total seconds"
(+ (string-to-number (substring time 6))
(*
(string-to-number (substring time 3 5))
60
)
(*
(string-to-number (substring time 0 2))
3600
)
)
)
(defun semitone-coefficient (semitones)
"Calculate the frequency coefficient for a given number of SEMITONES.
The coefficient represents the ratio of the frequency to the base frequency.
SEMITONES should be an integer between -12 and 12."
(if (and (integerp semitones) (<= -12 semitones 12))
(let ((semitone-ratio (expt 2 (/ 1.0 12))))
(expt semitone-ratio semitones))
(error "SEMITONES must be an integer between -12 and 12")))
(defun transpose-mp3 (input-file semitones output-file)
"Asynchronously transpose an MP3 file by a given number of SEMITONES using ffmpeg.
Prompts interactively for INPUT-FILE, SEMITONES, and OUTPUT-FILE if called interactively.
INPUT-FILE is the path to the original MP3 file.
SEMITONES is the number of semitones to transpose up (positive) or down (negative).
OUTPUT-FILE is the path to save the transposed MP3 file."
(interactive
(list
(read-file-name "Input MP3 file: " nil nil t nil 'file-readable-p)
(read-number "Semitones to transpose (e.g., 1 for up, -1 for down): ")
(read-file-name "Output MP3 file: " nil nil nil)))
(let* ((coefficient (semitone-coefficient semitones))
(pitch-filter (format "rubberband=pitch=%.12f" coefficient))
(command (format "ffmpeg -i \"%s\" -filter:a \"%s\" -acodec libmp3lame \"%s\""
(concat (expand-file-name (file-name-directory input-file)) (file-name-nondirectory input-file))
pitch-filter
(concat (expand-file-name (file-name-directory output-file)) (file-name-nondirectory output-file)))))
(message "Running: %s" command)
(async-shell-command command)))
(defun cut-media-file (origin startTime endTime newName)
"This function get in input:
- The path to a specific video
- The start time of the cut (00:00:00)
- The end time of the cut (00:00:00)
- The new name of the output
Perform a ffmpeg command to cut the input and generate the new output in the same directory
"
(interactive "FFile name to cut from:
sStart Time (00:00:00):
sEnd Time (00:00:00):
sNew Name: ")
(setq totalSeconds (- (timeToSeconds endTime) (timeToSeconds startTime)))
(setq ffmpegCommand (concat "ffmpeg -ss " startTime " -i \"" (concat (expand-file-name (file-name-directory origin)) (file-name-nondirectory origin)) "\" -t " (number-to-string totalSeconds) " -c:v copy -c:a copy \"" (concat (expand-file-name (file-name-directory origin)) newName) "\""))
(message "ffmpegCommand: %s" ffmpegCommand)
(async-shell-command ffmpegCommand)
)
(require 'seq)
(defun concatenate-media-files ()
"Concatenate a list of files with the same encoding in the same directory"
(interactive)
(setq
files (apply 'files-from-dired-current-directory '()))
(let* ((newFile (read-string "Insert the new file name: "))
(concatContent (seq-drop (seq-reduce (lambda (a b) (concat a "\nfile './" (replace-regexp-in-string "'" "\'" (file-name-nondirectory b)) "'")) files "") 1))
(unused (write-region concatContent nil "./concatFile.txt"))
(outputFile (expand-file-name (concat default-directory newFile)))
(ffmpegCommand (concat "ffmpeg -f concat -safe 0 -i ./concatFile.txt -c copy \"" outputFile "\"")))
;; (message "concatContent: %s - outputFile: %s - ffmpegCommand: %s" concatContent outputFile ffmpegCommand)
(shell-command ffmpegCommand)
(delete-file "./concatFile.txt")
)
)
(defun play-sound ()
"play the sound using ffplay"
(interactive)
(unless (command-exists-p "ffplay") (error "Please install ffplay (ffmpeg)"))
(setq files (funcall 'files-from-dired-current-directory))
(setq command
(mapconcat (lambda (file)
(let ((fileComplete (expand-file-name file))
(fileCompleteNoExtension (file-name-sans-extension (expand-file-name file))))
(format "ffplay -nodisp -autoexit \"%s\"" fileComplete fileCompleteNoExtension)))
files " && ")
)
(message "play sound command %s" command)
(call-process-shell-command command)
)
(defun preview-crop-media-file (file &optional height width topX topY)
"Preview using ffplay the crop of a mediafile.
file input crop to preview@
height of the output rectangle. if 0 or invalid, input file height will be used
width of the output rectangle. if 0 or invalid, input file width will be used
topX cordinate of the top left corner. Default 0
topY cordinate of the top left corner. Default 0"
(interactive (list
(read-file-name (format "File to preview: "))
(read-string (format "Height (default \"in_h\"): "))
(read-string (format "Width (default \"in_w\"): "))
(read-number (format "Top Left Corner X: ") 0)
(read-number (format "Top Left Corner Y: ") 0)
))
(unless (command-exists-p "ffplay") (error "Please install ffplay (ffmpeg)"))
(when (eq (string-to-number height) 0) (setq height "in_h"))
(when (eq (string-to-number width) 0) (setq width "in_w"))
(setq fileComplete (expand-file-name file))
;; (fileCompleteNoExtension (file-name-sans-extension (expand-file-name file))))
(setq command (format "ffplay -i %s -vf \"crop=%s:%s:%d:%d\"" fileComplete width height topX topY))
(message command)
(call-process-shell-command command nil 0)
)
(defun crop-media-file (file newFile &optional height width topX topY)
"Preview using ffplay the crop of a mediafile.
file to crop
newFile result file cropped
height of the output rectangle. if 0 or invalid, input file height will be used
width of the output rectangle. if 0 or invalid, input file width will be used
topX cordinate of the top left corner. Default 0
topY cordinate of the top left corner. Default 0"
(interactive (list
(read-file-name (format "File to crop: "))
(read-file-name (format "New File: "))
(read-string (format "Height (default \"in_h\"): "))
(read-string (format "Width (default \"in_w\"): "))
(read-number (format "Top Left Corner X: ") 0)
(read-number (format "Top Left Corner Y: ") 0)
))
(unless (command-exists-p "ffmpeg") (error "Please install ffmpeg"))
(when (eq (string-to-number height) 0) (setq height "in_h"))
(when (eq (string-to-number width) 0) (setq width "in_w"))
(setq fileComplete (expand-file-name file))
;;(fileCompleteNoExtension (file-name-sans-extension (expand-file-name file))))
(setq command (format "ffmpeg -i %s -vf \"crop=%s:%s:%d:%d\" %s" fileComplete width height topX topY newFile))
(message command)
(call-process-shell-command command nil 0)
)
Collect the functions for file conversions, mainly using shell commands
(defun convert-to-mp3 ()
(interactive)
(setq files (mapcar 'expand-file-name (apply 'files-from-dired-current-directory '())))
(mapcar (lambda (f) (shell-command
(format "ffmpeg -i \"%s\" -vn -ar 44100 -ac 2 -b:a 192k \"%s.mp3\"" f (file-name-sans-extension f)))) files)
)
(defun convert-to-gif (file)
(interactive "f")
(let ((fileComplete (expand-file-name file))
(fileCompleteNoExtension (file-name-sans-extension (expand-file-name file))))
(shell-command (format "ffmpeg -i %s -vf \"fps=10,scale=320:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse\" -loop 0 %s.gif" fileComplete fileCompleteNoExtension))))
Functions to get the name of the file and path to clipboard
(defun copy-file-name-to-kill-ring (filename-manipulate-func)
"Copy the current buffer file name to the kill-ring after the application of the input function."
(interactive)
(let ((filename (if (equal major-mode 'dired-mode)
default-directory
(buffer-file-name))))
(when filename
(let ((changedFilename (funcall filename-manipulate-func filename)))
(when changedFilename
(kill-new changedFilename))))))
(defun copy-file-name-and-path-to-kill-ring ()
"Copy the current buffer file name and path to kill-ring."
(interactive)
(copy-file-name-to-kill-ring 'identity))
(defun copy-just-file-name-to-kill-ring ()
"Copy just the current buffer file name to kill-ring."
(interactive)
(copy-file-name-to-kill-ring 'file-name-nondirectory))
Functions for formatting code.
(defun apply-case-char (startcol endcol function)
"apply the function to the char at start position. endcol not used"
(move-to-column startcol t)
(let ((c (string (following-char))))
(delete-char 1)
(insert (funcall function c)))
)
(defun upcase-first-region (begin end)
"Uppercase the first char of each line of the selected region"
(interactive "r")
(apply-on-rectangle 'apply-case-char begin end 'upcase)
)
;; Stefan Monnier <foo at acm.org>. It is the opposite of fill-paragraph
(defun unfill-paragraph (&optional region)
"Takes a multi-line paragraph and makes it into a single line of text."
(interactive (progn (barf-if-buffer-read-only) '(t)))
(let ((fill-column (point-max))
;; This would override `fill-column' if it's an integer.
(emacs-lisp-docstring-fill-column t))
(fill-paragraph nil region)))
;https://www.emacswiki.org/emacs/UnfillRegion
(defun unfill-region (beg end)
"Unfill the region, joining text paragraphs into a single
logical line. This is useful, e.g., for use with
`visual-line-mode'."
(interactive "*r")
(let ((fill-column (point-max)))
(fill-region beg end)))
(defun upcase-initial-word()
(interactive)
(search-forward-regexp "[[:space:]]*")
(let ((bounds (bounds-of-thing-at-point 'word)))
(upcase-initials-region (point) (cdr bounds)))
(forward-word)
)
(defun tidy-html ()
"Tidies the HTML content in the buffer using `tidy'"
(interactive)
(shell-command-on-region
;; beginning and end of buffer
(point-min)
(point-max)
;; command and parameters
"tidy -indent -wrap 150 -xml -utf8 -quiet"
;; output buffer
(current-buffer)
;; replace?
t
;; name of the error buffer
"*Tidy Error Buffer*"
;; show error buffer?
t))
Contains function to manage integers, in particular increase and decrease. source: https://emacsredux.com/blog/2013/07/25/increment-and-decrement-integer-at-point/
(require 'thingatpt)
(defun thing-at-point-goto-end-of-integer ()
"Go to end of integer at point."
(let ((inhibit-changing-match-data t))
;; Skip over optional sign
(when (looking-at "[+-]")
(forward-char 1))
;; Skip over digits
(skip-chars-forward "[[:digit:]]")
;; Check for at least one digit
(unless (looking-back "[[:digit:]]")
(error "No integer here"))))
(put 'integer 'beginning-op 'thing-at-point-goto-end-of-integer)
(defun thing-at-point-goto-beginning-of-integer ()
"Go to end of integer at point."
(let ((inhibit-changing-match-data t))
;; Skip backward over digits
(skip-chars-backward "[[:digit:]]")
;; Check for digits and optional sign
(unless (looking-at "[+-]?[[:digit:]]")
(error "No integer here"))
;; Skip backward over optional sign
(when (looking-back "[+-]")
(backward-char 1))))
(put 'integer 'beginning-op 'thing-at-point-goto-beginning-of-integer)
(defun thing-at-point-bounds-of-integer-at-point ()
"Get boundaries of integer at point."
(save-excursion
(let (beg end)
(thing-at-point-goto-beginning-of-integer)
(setq beg (point))
(thing-at-point-goto-end-of-integer)
(setq end (point))
(cons beg end))))
(put 'integer 'bounds-of-thing-at-point 'thing-at-point-bounds-of-integer-at-point)
(defun thing-at-point-integer-at-point ()
"Get integer at point."
(let ((bounds (bounds-of-thing-at-point 'integer)))
(string-to-number (buffer-substring (car bounds) (cdr bounds)))))
(put 'integer 'thing-at-point 'thing-at-point-integer-at-point)
(defun increment-integer-at-point (&optional inc)
"Increment integer at point by one.
ith numeric prefix arg INC, increment the integer by INC amount."
(interactive "p")
(let ((inc (or inc 1))
(n (thing-at-point 'integer))
(bounds (bounds-of-thing-at-point 'integer)))
(delete-region (car bounds) (cdr bounds))
(insert (int-to-string (+ n inc)))))
(defun decrement-integer-at-point (&optional dec)
"Decrement integer at point by one.
ith numeric prefix arg DEC, decrement the integer by DEC amount."
(interactive "p")
(increment-integer-at-point (- (or dec 1))))
Use date
unix command to insert date
(defun insert-current-date-iso-8601 ()
"Call the `date' unix command to insert the current date"
(interactive)
(if (command-exists-p "ffplay")
(insert (s-trim (shell-command-to-string "date -u +\"%Y-%m-%dT%H:%M:%SZ\"")))
(error "Please install ffplay (ffmpeg)"))
)
Custom Functions regading rectangles
(defun upcase-rectangle (b e)
"change chars in rectangle to uppercase"
(interactive "r")
(apply-on-rectangle 'apply-fun-rectangle-line b e 'upcase-region))
(defun downcase-rectangle (b e)
"change chars in rectangle to uppercase"
(interactive "r")
(apply-on-rectangle 'apply-fun-rectangle-line b e 'downcase-region))
(defun apply-fun-rectangle-line (startcol endcol function)
(when (= (move-to-column startcol) startcol)
(funcall function (point)
(progn (move-to-column endcol 'coerce)
(point)))))
function regarding the selection of text
(defun reselect-last-region ()
(interactive)
(let ((start (mark t))
(end (point)))
(goto-char start)
(call-interactively' set-mark-command)
(goto-char end)))
Generate random things to insert in the buffer
(defun xah-insert-random-number (NUM)
"Insert NUM random digits.
NUM default to 5.
Call `universal-argument' before for different count.
URL `http://xahlee.info/emacs/emacs/elisp_insert_random_number_string.html'
Version 2017-05-24"
(interactive "P")
(let (($charset "1234567890" )
($baseCount 10))
(dotimes (_ (if (numberp NUM) (abs NUM) 5 ))
(insert (elt $charset (random $baseCount))))))
(defun xah-insert-random-hex (NUM)
"Insert NUM random hexadecimal digits.
NUM default to 5.
Call `universal-argument' before for different count.
URL `http://xahlee.info/emacs/emacs/elisp_insert_random_number_string.html'
Version 2017-08-03"
(interactive "P")
(let (($n (if (numberp NUM) (abs NUM) 5 )))
(insert (format (concat "%0" (number-to-string $n) "x" ) (random (1- (expt 16 $n)))))))
(defun xah-insert-random-string (NUM)
"Insert a random alphanumerics string of length 5.
The possible chars are: A to Z, a to z, 0 to 9.
Call `universal-argument' before for different count.
URL `http://xahlee.info/emacs/emacs/elisp_insert_random_number_string.html'
Version 2018-08-03"
(interactive "P")
(let* (($charset "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
($baseCount (length $charset)))
(dotimes (_ (if (numberp NUM) (abs NUM) 5))
(insert (elt $charset (random $baseCount))))))
(defun xah-insert-random-uuid ()
"Insert a UUID.
This commands calls “uuidgen” on MacOS, Linux, and calls PowelShell on Microsoft Windows.
URL `http://xahlee.info/emacs/emacs/elisp_generate_uuid.html'
Version 2020-06-04"
(interactive)
(cond
((string-equal system-type "windows-nt")
(shell-command "pwsh.exe -Command [guid]::NewGuid().toString()" t))
((string-equal system-type "darwin") ; Mac
(shell-command "uuidgen | tr A-Z a-z | tr -d '\n'" t))
((string-equal system-type "gnu/linux")
(shell-command "uuidgen | tr A-Z a-z | tr -d '\n'" t))
(t
;; code here by Christopher Wellons, 2011-11-18.
;; and editted Hideki Saito further to generate all valid variants for "N" in xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx format.
(let ((myStr (md5 (format "%s%s%s%s%s%s%s%s%s%s"
(user-uid)
(emacs-pid)
(system-name)
(user-full-name)
(current-time)
(emacs-uptime)
(garbage-collect)
(buffer-string)
(random)
(recent-keys)))))
(insert (format "%s-%s-4%s-%s%s-%s"
(substring myStr 0 8)
(substring myStr 8 12)
(substring myStr 13 16)
(format "%x" (+ 8 (random 4)))
(substring myStr 17 20)
(substring myStr 20 32)))))))
Functions for manipulate text
(defun copy-line-from-point-as-string (&optional prefix suffix)
(unless prefix (setq prefix ""))
(unless suffix (setq suffix ""))
(setq currentPoint (point))
(end-of-line)
(setq result (concat prefix (buffer-substring-no-properties currentPoint (point)) suffix))
(eval result)
)
;; FROM http://xahlee.info/emacs/emacs/elisp_change_brackets.html
(defun xah-change-bracket-pairs ( @from-chars @to-chars)
"Change bracket pairs from one type to another.
For example, change all parenthesis () to square brackets [].
Works on selected text, or current text block.
When called in lisp program, @from-chars or @to-chars is a string of bracket pair. eg \"(paren)\", \"[bracket]\", etc.
The first and last characters are used. (the middle is for convenience in ido selection.)
If the string contains “,2”, then the first 2 chars and last 2 chars are used, for example \"[[bracket,2]]\".
If @to-chars is equal to string “none”, the brackets are deleted.
URL `http://xahlee.info/emacs/emacs/elisp_change_brackets.html'
Version 2020-11-01"
(interactive
(let (($bracketsList
'("(paren)"
"{brace}"
"[square]"
"<greater>"
"`emacs'"
"`markdown`"
"~tilde~"
"=equal="
"\"ascii quote\""
"[[double square,2]]"
"“curly quote”"
"‘single quote’"
"‹french angle›"
"«french double angle»"
"「corner」"
"『white corner』"
"【lenticular】"
"〖white lenticular〗"
"〈angle〉"
"《double angle》"
"〔tortoise〕"
"〘white tortoise〙"
"⦅white paren⦆"
"〚white square〛"
"⦃white curly⦄"
"〈pointing angle〉"
"⦑ANGLE WITH DOT⦒"
"⧼CURVED ANGLE⧽"
"⟦math square⟧"
"⟨math angle⟩"
"⟪math DOUBLE ANGLE⟫"
"⟮math FLATTENED PARENTHESIS⟯"
"⟬math WHITE TORTOISE SHELL⟭"
"❛HEAVY SINGLE QUOTATION MARK ORNAMENT❜"
"❝HEAVY DOUBLE TURNED COMMA QUOTATION MARK ORNAMENT❞"
"❨MEDIUM LEFT PARENTHESIS ORNAMENT❩"
"❪MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT❫"
"❴MEDIUM LEFT CURLY ORNAMENT❵"
"❬MEDIUM LEFT-POINTING ANGLE ORNAMENT❭"
"❮HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT❯"
"❰HEAVY LEFT-POINTING ANGLE ORNAMENT❱"
"none"
)))
(list
(ido-completing-read "Replace this:" $bracketsList )
(ido-completing-read "To:" $bracketsList ))))
(let ( $p1 $p2 )
(if (use-region-p)
(setq $p1 (region-beginning) $p2 (region-end))
(save-excursion
(if (re-search-backward "\n[ \t]*\n" nil "move")
(progn (re-search-forward "\n[ \t]*\n")
(setq $p1 (point)))
(setq $p1 (point)))
(if (re-search-forward "\n[ \t]*\n" nil "move")
(progn (re-search-backward "\n[ \t]*\n")
(setq $p2 (point)))
(setq $p2 (point)))))
(save-excursion
(save-restriction
(narrow-to-region $p1 $p2)
(let ( (case-fold-search nil)
$fromLeft
$fromRight
$toLeft
$toRight)
(cond
((string-match ",2" @from-chars )
(progn
(setq $fromLeft (substring @from-chars 0 2))
(setq $fromRight (substring @from-chars -2))))
(t
(progn
(setq $fromLeft (substring @from-chars 0 1))
(setq $fromRight (substring @from-chars -1)))))
(cond
((string-match ",2" @to-chars)
(progn
(setq $toLeft (substring @to-chars 0 2))
(setq $toRight (substring @to-chars -2))))
((string-match "none" @to-chars)
(progn
(setq $toLeft "")
(setq $toRight "")))
(t
(progn
(setq $toLeft (substring @to-chars 0 1))
(setq $toRight (substring @to-chars -1)))))
(cond
((string-match "markdown" @from-chars)
(progn
(goto-char (point-min))
(while
(re-search-forward "`\\([^`]+?\\)`" nil t)
(overlay-put (make-overlay (match-beginning 0) (match-end 0)) 'face 'highlight)
(replace-match (concat $toLeft "\\1" $toRight ) "FIXEDCASE" ))))
((string-match "tilde" @from-chars)
(progn
(goto-char (point-min))
(while
(re-search-forward "~\\([^~]+?\\)~" nil t)
(overlay-put (make-overlay (match-beginning 0) (match-end 0)) 'face 'highlight)
(replace-match (concat $toLeft "\\1" $toRight ) "FIXEDCASE" ))))
((string-match "ascii quote" @from-chars)
(progn
(goto-char (point-min))
(while
(re-search-forward "\"\\([^\"]+?\\)\"" nil t)
(overlay-put (make-overlay (match-beginning 0) (match-end 0)) 'face 'highlight)
(replace-match (concat $toLeft "\\1" $toRight ) "FIXEDCASE" ))))
((string-match "equal" @from-chars)
(progn
(goto-char (point-min))
(while
(re-search-forward "=\\([^=]+?\\)=" nil t)
(overlay-put (make-overlay (match-beginning 0) (match-end 0)) 'face 'highlight)
(replace-match (concat $toLeft "\\1" $toRight ) "FIXEDCASE" ))))
(t (progn
(progn
(goto-char (point-min))
(while (search-forward $fromLeft nil t)
(overlay-put (make-overlay (match-beginning 0) (match-end 0)) 'face 'highlight)
(replace-match $toLeft "FIXEDCASE" "LITERAL")))
(progn
(goto-char (point-min))
(while (search-forward $fromRight nil t)
(overlay-put (make-overlay (match-beginning 0) (match-end 0)) 'face 'highlight)
(replace-match $toRight "FIXEDCASE" "LITERAL")))))))))))
(defun xah-html-decode-percent-encoded-url ()
"Decode percent encoded URL of current line or selection.
Example:
%28D%C3%BCrer%29
becomes
(Dürer)
Example:
%E6%96%87%E6%9C%AC%E7%BC%96%E8%BE%91%E5%99%A8
becomes
文本编辑器
URL `http://xahlee.info/emacs/emacs/emacs_url_percent_decode.html'
Version 2018-10-26"
(interactive)
(let ( $p1 $p2 $input-str $newStr)
(if (use-region-p)
(setq $p1 (region-beginning) $p2 (region-end))
(setq $p1 (line-beginning-position) $p2 (line-end-position)))
(setq $input-str (buffer-substring-no-properties $p1 $p2))
(require 'url-util)
(setq $newStr (url-unhex-string $input-str))
(if (string-equal $newStr $input-str)
(progn (message "no change" ))
(progn
(delete-region $p1 $p2)
(insert (decode-coding-string $newStr 'utf-8))))))
(defun xah-html-encode-percent-encoded-url ()
"Percent encode URL in current line or selection.
Example:
http://example.org/(Dürer)
becomes
http://example.org/(D%C3%BCrer)
Example:
http://example.org/文本编辑器
becomes
http://example.org/%E6%96%87%E6%9C%AC%E7%BC%96%E8%BE%91%E5%99%A8
URL `http://xahlee.info/emacs/emacs/emacs_url_percent_decode.html'
Version 2018-10-26"
(interactive)
(let ($p1 $p2 $input-str $newStr)
(if (use-region-p)
(setq $p1 (region-beginning) $p2 (region-end))
(setq $p1 (line-beginning-position) $p2 (line-end-position)))
(setq $input-str (buffer-substring-no-properties $p1 $p2))
(require 'url-util)
(setq $newStr (url-encode-url $input-str))
(if (string-equal $newStr $input-str)
(progn (message "no change" ))
(progn
(delete-region $p1 $p2)
(insert $newStr)))))
(defun sort-words (reverse beg end)
"Sort words in region alphabetically, in REVERSE if negative.
Prefixed with negative \\[universal-argument], sorts in reverse.
The variable `sort-fold-case' determines whether alphabetic case
affects the sort order.
See `sort-regexp-fields'."
(interactive "*P\nr")
(sort-regexp-fields reverse "\\w+" "\\&" beg end))
(defun xah-insert-alphabets-az (&optional *use-uppercase-p)
"Insert letters a to z vertically.
If `universal-argument' is called first, use CAPITAL letters.
URL `http://ergoemacs.org/emacs/emacs_insert-alphabets.html'
Version 2015-11-06"
(interactive "P")
(let ((startChar (if *use-uppercase-p 65 97 )))
(dotimes (-i 26)
(insert (format "%c\n" (+ startChar -i))))))
(defun string-to-register (value registerName)
"Add the input string to a specific register"
(interactive
(list
(read-string "Enter value:")
(read-char "Enter register name:")))
(set-register registerName value)
)
Functions for manipulating the windows
(defun set-window-width (n)
"Set the selected window's width."
(adjust-window-trailing-edge (selected-window) (- n (window-width)) t))
(defun set-80-columns ()
"Set the selected window to 80 columns."
(interactive)
(set-window-width 80))
this files contains the functions that interact with youtube. Mainly using youtube-dl
.
(defun yt-dlp (youtubeUrl destinationPath outputFormat)
"Function that use yt-dlp to download the video and convert it to the specified output format"
(interactive
(list
(read-string "Youtube URL: ")
(read-directory-name "Destination directory: ")
(read-string "Output format\n(mp4|flv|ogg|webm|mkv|avi-best|aac|flac|mp3|m4a|opus|vorbis|wav): ")
)
)
(unless (command-exists-p "yt-dlp") (error "Please install yt-dlp"))
(setq supportedAudioFormats (list "best" "aac" "flac" "mp3" "m4a" "opus" "vorbis" "wav"))
(setq supportedVideoFormats (list "mp4" "flv" "ogg" "webm" "mkv" "avi"))
(cond
((member outputFormat supportedAudioFormats) (setq youtubeDlPCommand (format "yt-dlp -x --audio-format %s -o '%s%%(title)s-%%(id)s.%%(ext)s' %s" outputFormat destinationPath youtubeUrl)))
((member outputFormat supportedVideoFormats) (setq youtubeDlPCommand (format "yt-dlp --recode-video %s -o '%s%%(title)s-%%(id)s.%%(ext)s' %s" outputFormat destinationPath youtubeUrl)))
(t (error (message "Please insert a valid output format: %s" outputFormat)))
)
(async-shell-command youtubeDlPCommand)
)
(defun download-urls-or-region (&optional opt-urls)
"Select a region containing aria2c inputs. This will call aria2c asynchronously and dowload them in the current dir or in the specified one. if the region is empty it will ask for urls one by one"
(interactive)
; Requirements check: aria2c ;;;;;;;;;;;;
(unless (command-exists-p "aria2c") (error "Please install aria2"))
; input validation ;;;;;;;;;;;;;;;;;;;;
(setq urls (or
opt-urls
(when (use-region-p) (replace-regexp-in-string "\n" " " (buffer-substring-no-properties (region-beginning) (region-end))))
)
)
(when (equal urls nil)
(while (yes-or-no-p "Another aria2 input? ")
(setq urls (concat urls " " (read-string "Next aria2 input: ")))
))
(setq
urls (mapconcat (lambda (s) (concat "\"" s "\"")) (split-string (s-trim urls)) " ")
directory (read-directory-name "Select output directory: ")
aria2Command (concat "aria2c -d " directory " -Z " urls)
)
(print aria2Command)
(async-shell-command aria2Command)
)
(defun dired-do-command-interactive (command)
"Run COMMAND on marked files interactively. Any files not already open will be opened.
After this command has been run, any buffers it's modified will remain
open and unsaved."
(interactive "CRun on marked files M-x ")
(save-window-excursion
(mapc (lambda (filename)
(find-file filename)
(call-interactively command))
(dired-get-marked-files))))
(defun dired-do-command (command)
"Run COMMAND on marked files. Passing each file in input of the command, called not iteractively"
(interactive "CRun on marked files M-x ")
(save-window-excursion
(mapc (lambda (filename)
(funcall command filename))
(dired-get-marked-files))))
(defun xah-dired-sort ()
"Sort dired dir listing in different ways.
Prompt for a choice.
URL `http://ergoemacs.org/emacs/dired_sort.html'
Version 2015-07-30"
(interactive)
(let (-sort-by -arg)
(setq -sort-by (ido-completing-read "Sort by:" '( "date" "size" "name" "dir")))
(cond
((equal -sort-by "name") (setq -arg "-Al --si --time-style long-iso "))
((equal -sort-by "date") (setq -arg "-Al --si --time-style long-iso -t"))
((equal -sort-by "size") (setq -arg "-Al --si --time-style long-iso -S"))
((equal -sort-by "dir") (setq -arg "-Al --si --time-style long-iso --group-directories-first"))
(t (error "logic error 09535" )))
(dired-sort-other -arg )))
Functions to enhance magit capabilities
(defun parse-url (url)
"convert a git remote location as a HTTP URL"
(if (string-match "^http" url)
url
(replace-regexp-in-string "\\(.*\\)@\\(.*\\):\\(.*\\)\\(\\.git?\\)"
"https://\\2/\\3"
url)))
(defun magit-open-repo ()
"open remote repo URL"
(interactive)
(let ((url (magit-get "remote" "origin" "url")))
(progn
(browse-url (parse-url url))
(message "opening repo %s" url))))
Functions used by following sections to implement some IDE features
(defun line-contains-string (args)
"Check if the current line contains the input string"
(save-excursion
(beginning-of-line)
(when (search-forward args (line-end-position) t) t)
))
(defun searchFunction (backwardDrection)
"Return the regexp search function based on input direction:
- t: backward
- nil: forward
"
(if backwardDrection
're-search-backward
're-search-forward
))
(defun shell-clean-old-output (startingPhrase)
"When called on a shell buffer this function goes back to the beginning of the last compilation and delete the rest (old compilation). based on the input value"
(end-of-buffer)
(re-search-backward startingPhrase)
(delete-region (point) (goto-char (point-min)))
(end-of-buffer))
(defun event-file-navigation (startingFilePath endingFilePath &optional notSplitWindow)
"Starting from an output buffer this function:
- Search for the starting file path in the output from current buffer
- Parse the line for the target source file
- move to the file: it creates a windows if the count-windows is = 1 and the parameter is false
"
(beginning-of-line)
(search-forward-regexp startingFilePath)
(setq filenamePathPos (point))
(search-forward-regexp endingFilePath)
(left-char)
(setq filePath (expand-file-name (string-trim (buffer-substring filenamePathPos (point)))))
(when (and notSplitWindow (= (count-windows) 1)) (split-window-right))
(other-window 1)
(message "find file: %s" filePath)
(find-file (string-trim filePath)))
(defun goto-next-warn-error (eventFileNavigationF searchPattern lineDelimiter columnDelimiter postF &optional errorMessage backwardSearch isRegexp)
"Template for the goto-next-warn-error function used to navigate to the specific error.
Usually it is used with a customized version of the above event-file-navigation function.
"
(unless errorMessage (setq errorMessage ""))
(unless isRegexp (setq errorMessage (regexp-quote errorMessage)))
(setq searchRegexp (concat searchPattern errorMessage))
(condition-case
nil
(funcall (searchFunction backwardSearch) searchRegexp)
(error (user-error "no match found for %s" errorMessage))
)
(when backwardSearch (goto-char (match-beginning 0)))
(funcall eventFileNavigationF t)
(other-window -1)
(parse-go-to-line-or-column lineDelimiter 'goto-line)
(other-window -1)
(parse-go-to-line-or-column columnDelimiter 'right-char)
(recenter-top-bottom)
(other-window -1)
(funcall postF))
(defun parse-go-to-line-or-column (separator gotoFunction)
"Higher order function: applies the input function to the number parsed from current position based on the input separator
eg. filePath:100:10
filePath(100,10)
applied most of the time with goto-line or right-char
"
(right-char)
(setq filenamePathPos (point))
(search-forward-regexp separator)
(left-char)
(setq fileLineOrColumn (buffer-substring filenamePathPos (point)))
(other-window 1)
(funcall gotoFunction (string-to-number fileLineOrColumn))
fileLineOrColumn)
(defun extract-code-line-or-region-template (value postDefinitionSyntaxValue EndSyntaxValue function parameterPrefix parameterPostfix postDefinitionSyntaxFunc EndSyntaxFunc name parameters from to)
"Template for extracting code to value or function:
Based on the input it this extract the selected code to the closest empty line above.
- value: syntax for values in target laguage
- postDefinitionSyntaxValue: what you put between the name of the value and its actual value. eg (= in scala)
- EndSyntaxValue: what to put at the end of the definition of value body. Eg in js it's ';'
- function: syntax for function in target laguage
- ParameterPrefix: Between the name of the reference and the parameters in some
- parameterPostfix: after the parameters list
- postDefinitionSyntaxFunc: what you put between the name + parameters and the body of the function. eg (= in scala)
- EndSyntaxFunc: what to put at the end of the definition of function body. Eg in js it's '}' for functions
- name: name of the extracted value/function
- parameters: parameters of the extracted function
- from: start of the region
- to: end of the region
"
;; extract code, cut if region or cut from point to end of the line
(setq code (buffer-substring from to))
(delete-region from to)
;; Generate code
(setq resultDefinition (if (string-blank-p parameters)
(concat value name postDefinitionSyntaxValue code EndSyntaxValue)
(concat function name parameterPrefix parameters parameterPostfix postDefinitionSyntaxFunc code EndSyntaxFunc)))
(setq resultReference (if (string-blank-p parameters)
name
(concat name parameterPrefix parameters parameterPostfix)))
;; Put the resultReference at point
(insert resultReference)
;; Move to the closest ^$ line and insert the resultDefinition
(re-search-backward "^$")
(insert resultDefinition)
(newline)
)
(defun goto-definition (type typeDefinitionRegexp)
"Higher order function that just apply the regexp in input to move the cursor at the definition point.
eg. \\(.*class type .*\\|.*trait type .*\\|.*object type .*\\|.*type type .*\\) to go to a scala definition
- type: the type to search for
- typedefinitionregexp: function that builds the regexp used in the search
"
(project-find-regexp (funcall typeDefinitionRegexp type))
)
(defun build-import (inputType existingImportRegexp typeDefinitionRegexp build-import-from-existing-import-or-source importInsertionFunc)
"Template function to import a specific type:
- type: target type
- existingImportRegexp: lambda that computes the regexp, used to search for exisiting type imports.
- typeDefinitionRegexp: lambda that computes the regexp, used to search for exisiting type definition.
- build-import-from-existing-import-or-source: computes the import to insert. Very context dependent(cursor's position)
- importInsertionFunc: executed into the origin buffer, this decides how/where to insert the import.
"
(setq startingBuffer (buffer-name))
(condition-case nil
(project-find-regexp (funcall existingImportRegexp inputType))
(error (goto-definition inputType typeDefinitionRegexp))
)
;; In linux, if 1 result is found xref is not created, and the focus
;; goes directly to the match
(when (get-buffer "*xref*")
(switch-to-buffer "*xref*")
(xref-next-line)
(xref-goto-xref t)
)
(setq result (funcall build-import-from-existing-import-or-source inputType startingBuffer))
(switch-to-buffer startingBuffer)
(funcall importInsertionFunc result))
(defun remove-unused-import (unusedImportSearch gotoUnusedImport importBoundFunc narrowImportFix)
"Template function that clean the unused import applying the input functions"
(funcall gotoUnusedImport unusedImportSearch t t)
(setq importBounds (funcall importBoundFunc)
startImport (car importBounds)
endImport (cadr importBounds)
targetType (point))
(save-restriction
(narrow-to-region startImport endImport)
(beginning-of-buffer)
(funcall narrowImportFix targetType)
)
(other-window -1)
)
(setq githubApiCache (make-hash-table :test 'equal))
(defun github-search-open-repo (searchString repo)
"search in the github repo if there's a file containing the searchString, prompt a selection to the user to choose from and then open a new buffer with the content of that file. repo formatted as org/repo (typelevel/cats)"
(interactive (list
(read-string (format "searchTerm (%s): " (thing-at-point 'word))
nil nil (thing-at-point 'word))
(read-string "repo: ")
))
(setq cacheKeySelectedFiles (concat repo "/" searchString)
cacheSelectedFilesJson (gethash cacheKeySelectedFiles githubApiCache)
matchingFilesJson (if cacheSelectedFilesJson
cacheSelectedFilesJson
(prog1
(setq searchQueryParameter (concat searchString "+in:file+repo:" repo)
searchUrl (concat "https://api.github.com/search/code?q=" searchQueryParameter)
searchJsonFull (with-current-buffer (url-retrieve-synchronously searchUrl) (json-parse-string (seq-drop-while (lambda (c) (not (char-equal c (string-to-char "{"))))(buffer-string))))
matchingFiles (gethash "items" searchJsonFull)
)
(puthash cacheKeySelectedFiles matchingFiles githubApiCache)
))
matchingFilesNames (mapcar (lambda (x) (gethash "name" x)) matchingFilesJson)
selectedFile (completing-read "select target file: " matchingFilesNames)
cacheKeyRawContent (concat repo "/" searchString "/" selectedFile)
cacheRawContent (gethash cacheKeyRawContent githubApiCache))
(if cacheRawContent
(progn
(setq newBuff (generate-new-buffer selectedFile))
(switch-to-buffer-other-window newBuff)
(insert cacheRawContent)
(beginning-of-buffer)
(search-forward searchString)
)
(progn
(setq selectedElemJson (elt (seq-filter (lambda (x) (string-equal (gethash "name" x) selectedFile)) matchingFilesJson) 0)
selectedElemPath (gethash "path" selectedElemJson)
repositoryContentUrl (seq-take-while (lambda (c) (not (char-equal c (string-to-char "{")))) (gethash "contents_url" (gethash "repository" selectedElemJson)))
selectedElementContentUrl (concat repositoryContentUrl selectedElemPath)
)
(with-current-buffer (url-retrieve-synchronously selectedElementContentUrl)
(progn
(browse-url-emacs
(gethash "download_url" (json-parse-string (seq-drop-while (lambda (c) (not (char-equal c (string-to-char "{")))) (buffer-string)))))
(puthash cacheKeyRawContent (buffer-string) githubApiCache)
(search-forward searchString)
))
)
)
)
Functions used specifically for dealing with scala code.
(setq scalaDefinitionRegex (lambda (type) (concat "\\(.*class " type ".*\\|.*trait " type ".*\\|.*object " type ".*\\|.*type " type ".*\\|.*enum " type ".*\\)")))
(defun sbt-event-file-navigation (&optional notSplitWindow)
"Navigate to the file that has a problem. it can navigate using a
different window."
(funcall 'event-file-navigation "] \\(-- .*: \\)?" ":" notSplitWindow))
(defun scala-build-import-from-existing-import-or-source (type startingBuffer)
"Considering the cursor is at the beginning of the target import line
or into the scala source file containing the definition of the
target file. This functions return the import to insert into the
dependent scala source file."
(if (string= (current-word) "import")
(copy-line-from-point-as-string) ;; copy import line
(concat "import " (path-to-package (buffer-file-name)) "." type) ;; copy package and make it an import
))
(defun path-to-package (path)
"transform a path to a package"
(string-join
(butlast
(s-split "/"
(nth 1
(split-string path "scala/")
)
)
) ".")
)
(defun scala-path-to-package ()
"transform a path to a package, current buffer"
(interactive)
(setq package (path-to-package (buffer-file-name)))
(insert (concat "package " package))
)
; keybinded functions ;;;;;;;;;;;;;;;;;
(defun sbt-shell-clean-old-output ()
"When called on a shell buffer this function goes back to the beginning of the last compilation and delete the rest (old compilation)"
(interactive)
(funcall 'shell-clean-old-output "\\(\\[info\\] Compiling\\|^sbt:.*> [^[:space:]]\\)"))
(defun scala-goto-next-warn-error (&optional errorMessage backwardSearch isRegexp)
"Search into an sbt output for the first warning/error, starting from cursor position, and move to it"
(interactive)
(goto-next-warn-error 'sbt-event-file-navigation ".*\\.scala.*" ":" "\\(:\\|$\\)" '(lambda () (other-window 1) ) errorMessage backwardSearch isRegexp))
(defun scala-import-bounds ()
"Return the import region bounds"
(save-excursion
(search-backward-regexp "\\({\\|import\\)")
(if (string= (current-word) "import")
(progn
(setq startOfImport (point)
endOfImport (if (char-equal (char-before (line-end-position)) ?{)
(progn
(end-of-line)
(cdr (bounds-of-thing-at-point 'sexp)))
(line-end-position)
))
(list startOfImport endOfImport)
)
(progn
(setq endOfImport (cdr (bounds-of-thing-at-point 'sexp)))
(search-backward-regexp "\\({\\|import\\)")
(list (point) endOfImport)
)
)))
(defun scala-remove-unused-import ()
"Parse a shell/sbt output in search of the first unused import and remove it"
(interactive)
(funcall 'remove-unused-import
"\\(Unused Import\\|\\(
.*\\)\\{2\\}
.*unused import$\\)"
'scala-goto-next-warn-error
'scala-import-bounds
(lambda (targetType)
(if (search-forward "," nil t)
(progn ;; multi import
(goto-char targetType)
(setq targetTypeBounds (bounds-of-thing-at-point 'word))
(setq startKillTypeTarget (car targetTypeBounds))
(setq endKillTypeTarget (cdr targetTypeBounds))
(kill-region startKillTypeTarget endKillTypeTarget)
(if (search-backward "," nil t)
(progn
(search-forward ",")
(delete-backward-char 1)
)
(delete-forward-char 1)
)
)
(delete-region (point-min) (point-max)) ;; single import
)
)
))
(defun scala-import-type-at-point (type)
"Try to import into the current file the type at point"
(interactive (list
(read-string (format "type (%s): " (thing-at-point 'word))
nil nil (thing-at-point 'word))))
(funcall 'build-import
type
(lambda (type) (concat "import.*" type "$"))
scalaDefinitionRegex
'scala-build-import-from-existing-import-or-source
(lambda (result) (save-excursion
(beginning-of-buffer)
(end-of-line)
(search-forward-regexp "^$")
(newline)
(insert result)
))
))
(defun scala-extract-code-line-or-region (name &optional parameters from to)
"Extract the code to val or def:
Require:
- Name of the val/def
- Optional list of parameters (if empty it will be a val)
if no code region is selected then it extracts the rest of the line from current position
Return type not specified.
"
(interactive (list
(read-string "value/function name: " )
(progn
(setq
param (read-string "param name (RET to finish): ")
params nil
)
(while (not (equal "" (s-trim param)))
(push (s-trim param) params)
(setq param (read-string "param name (RET to finish): "))
)
(mapconcat 'identity (reverse params) ", ")
)
(if (use-region-p) (region-beginning) (point))
(if (use-region-p) (region-end) (line-end-position))
))
(funcall 'extract-code-line-or-region-template "val " " = " nil "def " "(" ")" " = {" "}" name parameters from to)
)
(defun scala-goto-definition (type)
"Using the higher order function and the lambda defined above, it search in the project for the definition of the input type"
(interactive (list
(read-string (format "type (%s): " (thing-at-point 'word))
nil nil (thing-at-point 'word))))
(goto-definition type scalaDefinitionRegex)
)
(defun scala-open-doc (queryType lib)
"Open the scala doc in browser searching for the input queryType"
(interactive (list
(read-string (format "type (%s): " (thing-at-point 'word))
nil nil (thing-at-point 'word))
(completing-read "Library: "
'("Cats" "Cats-Effect" "Circe" "Doobie" "Http4s" "Monocle" "Munit" "Natchez" "Scalacheck" "Skunk" "Spark" "Standard Library" "Feral" "Fs2" "Weaver") nil t)
))
(require 'browse-url)
(setq libUrlPrefix (cond
((string= lib "Cats") "https://typelevel.org/cats/api/cats/index.html?search=")
((string= lib "Cats-Effect") "https://typelevel.org/cats-effect/api/3.x/?search=")
((string= lib "Circe") "https://circe.github.io/circe/api/index.html?search=")
((string= lib "Doobie") "https://javadoc.io/doc/org.tpolecat/doobie-core_3/latest/index.html")
((string= lib "Http4s") "https://www.javadoc.io/doc/org.http4s/http4s-docs_2.13/latest/index.html?search=")
((string= lib "Monocle") "https://javadoc.io/doc/com.github.julien-truffaut/monocle-core_3.0.0-RC3/latest/api/monocle/Monocle$.html")
((string= lib "Munit") "https://www.javadoc.io/doc/org.scalameta/munit_3/latest/index.html")
((string= lib "Natchez") "https://www.javadoc.io/doc/org.tpolecat/natchez-core_2.13/0.0.23/index.html?search=")
((string= lib "Skunk") "https://www.javadoc.io/doc/org.tpolecat/skunk-core_3/latest/index.html")
((string= lib "Feral") "https://www.javadoc.io/static/org.typelevel/feral-docs_3/0.2.3/feral/lambda.html?search=")
((string= lib "Fs2") "https://oss.sonatype.org/service/local/repositories/releases/archive/co/fs2/fs2-core_2.12/3.0.4/fs2-core_2.12-3.0.4-javadoc.jar/!/fs2/index.html?search=")
((string= lib "Scalacheck") "https://javadoc.io/doc/org.scalacheck/scalacheck_3/latest/index.html")
((string= lib "Smithy4s") "https://javadoc.io/doc/com.disneystreaming.smithy4s/smithy4s-core_3/0.9.0/index.html")
((string= lib "Spark") "https://spark.apache.org/docs/latest/api/scala/?search=")
((string= lib "Weaver") "https://www.javadoc.io/doc/com.disneystreaming/weaver-cats_3/latest/index.html")
(t "https://www.scala-lang.org/api/current/index.html?search=")
))
(browse-url (concat libUrlPrefix queryType))
)
(defun scala-github-search-open-repo (queryType repo)
"Search on github for the querytype in the given repo and open the selected file in a separate buffer"
(interactive (list
(read-string (format "searchTerm (%s): " (thing-at-point 'word))
nil nil (thing-at-point 'word))
(completing-read "repository: "
'("typelevel/cats" "typelevel/cats-effect" "http4s/http4s" "tpolecat/doobie" "typelevel/fs2" "circe/circe" "scalameta/munit" "tpolecat/skunk" "optics-dev/Monocle" "softwaremill/tapir" "typelevel/scalacheck") nil nil)
))
(github-search-open-repo queryType repo)
)
(defun scala-string-to-strip-margin-string (&optional $from $to)
"Escape the string selected as scala multiline string with strip margin |.
Reference: https://www.oreilly.com/library/view/scala-cookbook/9781449340292/ch01s03.html"
(interactive
(if (use-region-p)
(list (region-beginning) (region-end))
(let ((bds (bounds-of-thing-at-point 'paragraph)) )
(list (car bds) (cdr bds)) ) ) )
(let (inputStr outputStr)
(setq inputStr (buffer-substring-no-properties $from $to))
(setq outputStr
(let* (
(case-fold-search t)
(first-replace (replace-regexp-in-string "^" "|" inputStr))
)
(substring first-replace 1 (length first-replace))
))
(save-excursion
(delete-region $from $to)
(goto-char $from)
(insert outputStr)
(unless (eq ?\N{QUOTATION MARK} (char-before)) (end-of-line))
(insert ".stripMargin")
)))
Functions useful when dealing with Haskell.
(setq haskellDefinitionRegex (lambda (type) (concat "\\(.*data " type ".*\\|.*type " type ".*\\|.*newtype " type ".*\\|" type " ::.*\\)")))
(defun hs-shell-clean-old-output ()
"When called on a shell buffer this function goes back to the beginning of the last compilation and delete the rest (old compilation)"
(interactive)
(funcall 'shell-clean-old-output "\\(Building library for \\|[1-9][0-9]? error[s]?\\|[1-9]+ warning[s]?\\|All good\\|λ> \\)"))
(defun hs-event-file-navigation (&optional notSplitWindow)
"Navigate to the file that has a problem. it can navigate using a
different window."
(beginning-of-line) ;; Often called from the end of the line of the file path targeted
(funcall 'event-file-navigation "" ":" notSplitWindow))
(defun hs-goto-next-warn-error (&optional errorMessage backwardSearch isRegexp)
"Search into an haskell output for the first warning/error, starting from cursor position, and move to it"
(interactive)
(goto-next-warn-error 'hs-event-file-navigation ".*\\.hs:.*" ":" "[:-]" '(lambda () () ) errorMessage backwardSearch isRegexp))
(defun hs-extract-code-line-or-region (name &optional parameters from to)
"Extract the code to val or def:
Require:
- Name of the val/def
- Optional list of parameters (if empty it will be a val)
if no code region is selected then it extracts the rest of the line from current position
Return type not specified.
"
(interactive (list
(read-string "value/function name: " )
(progn
(setq
param (read-string "param name (RET to finish): ")
params nil
)
(while (not (equal "" (s-trim param)))
(push (s-trim param) params)
(setq param (read-string "param name (RET to finish): "))
)
(mapconcat 'identity (reverse params) " ")
)
(if (use-region-p) (region-beginning) (point))
(if (use-region-p) (region-end) (line-end-position))
))
(funcall 'extract-code-line-or-region-template nil " = " nil nil " " nil " = " nil name parameters from to))
(defun hs-goto-next-unused-import (&optional errorMessage backwardSearch isRegexp)
"Search into an haskell output for the unused import, and move to it.
Special case of hs-goto-next-warn-error since the output doesn't provide
the correct column position"
(interactive)
(unless errorMessage (setq errorMessage ""))
(unless isRegexp (setq errorMessage (regexp-quote errorMessage)))
(setq searchRegexp (concat (getenv "HOME") ".*\\.hs.*" errorMessage))
(condition-case
nil
(funcall (searchFunction backwardSearch) searchRegexp)
(error (user-error "no match found for %s" errorMessage))
)
(hs-event-file-navigation t)
(other-window -1)
(parse-go-to-line-or-column ":" 'goto-line)
(other-window -1)
(save-excursion
(search-forward "The import of ‘")
(setq p1 (point))
(search-forward "’")
(left-char)
(setq targetImport (buffer-substring-no-properties p1 (point)))
)
(other-window 1)
(search-forward targetImport)
(search-backward targetImport) ;;to move at the start of the match
)
(defun hs-import-bounds ()
"Return the import region bounds"
(save-excursion
(search-backward-regexp "\\((\\|import\\)")
(if (char-equal (char-after (point)) ?\( )
(progn
(setq startBracketPoint (point))
(search-backward-regexp "\\((\\|import\\)")
(setq startOfImport (point))
(goto-char startBracketPoint)
(goto-char (cdr (bounds-of-thing-at-point 'sexp)))
(list startOfImport (line-end-position))
)
(progn
(setq startOfImport (point)
endOfImport (if (char-equal (char-before (line-end-position)) ?\( )
(progn
(end-of-line)
(goto-char (cdr (bounds-of-thing-at-point 'sexp)))
(line-end-position)
)
(line-end-position)
))
(list startOfImport endOfImport)
)
)))
(defun hs-remove-unused-import ()
"Parse a shell output (stack) in search of the first unused import and remove it"
(interactive)
(funcall 'remove-unused-import
".*Wunused-imports.*$"
'hs-goto-next-unused-import
'hs-import-bounds
(lambda (targetType)
(if (search-forward "," nil t)
(progn ;; multi import
(goto-char targetType)
(setq targetTypeBounds (bounds-of-thing-at-point 'word))
(setq startKillTypeTarget (car targetTypeBounds))
(setq endKillTypeTarget (cdr targetTypeBounds))
(kill-region startKillTypeTarget endKillTypeTarget)
(if (search-backward "," nil t)
(progn
(search-forward ",")
(delete-backward-char 1)
)
(delete-forward-char 1)
)
)
(delete-region (point-min) (point-max)) ;; single import
)
)
))
(defun hs-build-import-from-existing-import-or-source (type startingBuffer)
"Considering the cursor is at the beginning of the target import line
or into the haskell source file containing the definition of the
target file. This functions return the import to insert into the
dependent haskell source file."
(if (string= (current-word) "import")
(copy-line-from-point-as-string) ;; copy import line
(progn
(beginning-of-buffer)
(search-forward "module ")
(setq moduleStartPoint (point))
(search-forward-regexp " \\|$")
(setq moduleName (s-trim (buffer-substring-no-properties moduleStartPoint (point))))
(concat "import " moduleName " (" type ")")
)
))
(defun hs-import-type-at-point (type)
"Try to import into the current file the type at point"
(interactive (list
(read-string (format "type (%s): " (thing-at-point 'word))
nil nil (thing-at-point 'word))))
(funcall 'build-import
type
(lambda (type) (concat "^import .*" type "[ ,]?.*)$"))
haskellDefinitionRegex
'hs-build-import-from-existing-import-or-source
(lambda (result) (save-excursion
(beginning-of-buffer)
(search-forward "where")
(next-line)
(newline 2)
(previous-line)
(insert result)
))
))
(defun hs-string-to-multiline-string (&optional $from $to)
"Escape the string selected as haskell multiline string"
(interactive
(if (use-region-p)
(list (region-beginning) (region-end))
(let ((bds (bounds-of-thing-at-point 'paragraph)) )
(list (car bds) (cdr bds)) ) ) )
(let (inputStr outputStr)
(setq inputStr (buffer-substring-no-properties $from $to))
(setq outputStr
(let* (
(case-fold-search t)
(first-replace (replace-regexp-in-string "$" (regexp-quote "\\n\\") inputStr))
(second-replace (replace-regexp-in-string "^" (regexp-quote "\\") first-replace))
(remove-starting-backslash (substring second-replace 1 (length second-replace)))
)
(substring remove-starting-backslash 0 (- (length remove-starting-backslash) 3))
))
(save-excursion
(delete-region $from $to)
(goto-char $from)
(insert outputStr))))
(defun hs-goto-definition (type)
"Using the higher order function and the lambda defined above, it search in the project for the definition of the input type"
(interactive (list
(read-string (format "type (%s): " (thing-at-point 'word))
nil nil (thing-at-point 'word))))
(goto-definition type haskellDefinitionRegex)
)
(defun hs-hoogle (hoogleSearch)
"Oper a Browser tab and search the term in hoogle"
(interactive (list
(read-string (format "hoogle search (%s): " (thing-at-point 'word))
nil nil (thing-at-point 'word))))
(require 'browse-url)
(browse-url (concat "https://hoogle.haskell.org/?hoogle=" hoogleSearch))
)
Functions useful when dealing with typescript.
(setq typescriptDefinitionRegex (lambda (type) (concat "\\(.*class " type ".*\\|.*interface " type ".*\\|.*type " type ".*\\)")))
(defun ts-shell-clean-old-output ()
"When called on a shell buffer this function goes back to the beginning of the last compilation and delete the rest (old compilation)"
(interactive)
(funcall 'shell-clean-old-output "\\(<s> \\[webpack\\.Progress\\] 100% \\|📦 Building\\|.*\\bnest\\b.*\\|.*Starting incremental compilation.*\\|.*jest.*\\|^> \\)")
)
(defun ts-event-file-navigation (&optional notSplitWindow)
"Navigate to the file that has a problem. it can navigate using a
different window."
(unless (equal (point) (point-min))
(previous-line) ;; Often called from the line AFTER the actual file path targeted
)
(condition-case nil
(funcall 'event-file-navigation (regexp-quote "[tsl] ERROR in ") "(" notSplitWindow)
(error (progn
(search-forward-regexp "^[:alpha:]")
(beginning-of-line)
(funcall 'event-file-navigation "" ":" notSplitWindow)
)
)
)
)
(defun ts-goto-next-warn-error (&optional errorMessage backwardSearch isRegexp)
"Search into an typescript output for the first warning/error, starting from cursor position, and move to it"
(interactive)
(goto-next-warn-error 'ts-event-file-navigation ".*TS.*: " "\\(,\\|:\\)" "\\()\\| \\)" '(lambda () () ) errorMessage backwardSearch isRegexp)
)
(defun ts-extract-code-line-or-region (name &optional parameters from to)
"Extract the code to val or def:
Require:
- Name of the val/def
- Optional list of parameters (if empty it will be a val)
if no code region is selected then it extracts the rest of the line from current position
Return type not specified.
"
(interactive (list
(read-string "value/function name: " )
(progn
(setq
separator (read-string "insert separartor(,): " nil nil ",")
param (read-string "param name (RET to finish): ")
params nil
)
(while (not (equal "" (s-trim param)))
(push (s-trim param) params)
(setq param (read-string "param name (RET to finish): "))
)
(reverse (cons (car params) (mapcar (lambda (x) (concat x separator)) (cdr params))))
)
(if (use-region-p) (region-beginning) (point))
(if (use-region-p) (region-end) (line-end-position))
))
(funcall 'extract-code-line-or-region-template "var " " = " ";" "function " "(" ")" " { \n return " ";\n }" name parameters from to)
)
(defun ts-build-import-from-existing-import-or-source (type startingBuffer)
"Considering the cursor is at the beginning of the target import line
or into the typescript source file containing the definition of the
target file. This functions return the import to insert into the
dependent typescript source file."
(if (string= (current-word) "import")
(copy-line-from-point-as-string) ;; copy import line
(concat "import { " type " } from '" (s-chop-suffixes '(".ts" ".tsx" ".ts.html") (file-relative-name (buffer-file-name) startingBuffer)) "';")
)
)
(defun ts-import-type-at-point (type)
"Try to import into the current file the type at point"
(interactive (list
(read-string (format "type (%s): " (thing-at-point 'word))
nil nil (thing-at-point 'word))))
(funcall 'build-import
type
(lambda (type) (concat "^import .*" " " type "[ ,]" ".*} from '.*';$"))
typescriptDefinitionRegex
'ts-build-import-from-existing-import-or-source
(lambda (result) (save-excursion
(beginning-of-buffer)
(newline)
(previous-line)
(insert result)
))
)
)
(defun ts-import-bounds ()
"Return the import region bounds"
(save-excursion
(search-backward-regexp "\\({\\|import\\)")
(if (char-equal (char-after (point)) ?{)
(progn
(setq startBracketPoint (point))
(search-backward-regexp "\\({\\|import\\)")
(setq startOfImport (point))
(goto-char startBracketPoint)
(goto-char (cdr (bounds-of-thing-at-point 'sexp)))
(list startOfImport (line-end-position))
)
(progn
(setq startOfImport (point)
endOfImport (if (char-equal (char-before (line-end-position)) ?{)
(progn
(end-of-line)
(goto-char (cdr (bounds-of-thing-at-point 'sexp)))
(line-end-position)
)
(line-end-position)
))
(list startOfImport endOfImport)
)
))
)
(defun ts-remove-unused-import ()
"Parse a shell output in search of the first unused import and remove it"
(interactive)
(funcall 'remove-unused-import
".*is declared but.*$"
'ts-goto-next-warn-error
'ts-import-bounds
(lambda (targetType)
(if (search-forward "," nil t)
(progn ;; multi import
(goto-char targetType)
(setq targetTypeBounds (bounds-of-thing-at-point 'word))
(setq startKillTypeTarget (car targetTypeBounds))
(setq endKillTypeTarget (cdr targetTypeBounds))
(kill-region startKillTypeTarget endKillTypeTarget)
(if (search-backward "," nil t)
(progn
(search-forward ",")
(delete-backward-char 1)
)
(delete-forward-char 1)
)
)
(delete-region (point-min) (point-max)) ;; single import
)
)
)
)
(defun ts-goto-definition (type)
"Using the higher order function and the lambda defined above, it search in the project for the definition of the input type"
(interactive (list
(read-string (format "type (%s): " (thing-at-point 'word))
nil nil (thing-at-point 'word))))
(goto-definition type typescriptDefinitionRegex)
)
Functions used specifically for dealing with c# code.
(setq csharpDefinitionRegex (lambda (type) (concat "\\(.*class " type ".*\\|.*interface " type ".*\\|.*enum " type ".*\\)")))
(defun dotnet-event-file-navigation (&optional notSplitWindow)
"Navigate to the file that has a problem. it can navigate using a
different window."
(funcall 'event-file-navigation "^" "(" notSplitWindow))
(defun dotnet-build-import-from-existing-import-or-source (type startingBuffer)
"Considering the cursor is at the beginning of the target import line
or into the .net source file containing the definition of the
target file. This functions return the import to insert into the
dependent .net source file."
(message "test")
(if (string= (current-word) "using")
(copy-line-from-point-as-string) ;; copy import line
(concat "using " (type-namespace) ";") ;; copy namespace and make it an import
))
(defun type-namespace ()
"return the namespace of the current file"
(save-excursion
(beginning-of-buffer)
(search-forward "namespace ")
(buffer-substring-no-properties (point) (line-end-position))
)
)
; keybinded functions ;;;;;;;;;;;;;;;;;
(defun csharp-shell-clean-old-output ()
"When called on a shell buffer this function goes back to the beginning of the last compilation and delete the rest (old compilation)"
(interactive)
(funcall 'shell-clean-old-output "^Build .*$"))
(defun csharp-goto-next-warn-error (&optional errorMessage backwardSearch isRegexp)
"Search into an sbt output for the first warning/error, starting from cursor position, and move to it"
(interactive)
(forward-line)
(goto-next-warn-error 'dotnet-event-file-navigation ".*\\.cs.*" "," ")" '(lambda () (progn
(other-window -1)
(left-char)) ) errorMessage backwardSearch isRegexp))
(defun csharp-import-type-at-point (type)
"Try to import into the current file the type at point"
(interactive (list
(read-string (format "type (%s): " (thing-at-point 'word))
nil nil (thing-at-point 'word))))
(funcall 'build-import
type
(lambda (type) (concat "using.*" type "$"))
csharpDefinitionRegex
'dotnet-build-import-from-existing-import-or-source
(lambda (result) (save-excursion
(beginning-of-buffer)
(newline)
(previous-line)
(insert result)
))
))
(defun csharp-extract-code-line-or-region (name &optional parameters from to)
"Extract the code to val or def:
Require:
- Name of the val/def
- Optional list of parameters (if empty it will be a val)
if no code region is selected then it extracts the rest of the line from current position
Return type not specified.
"
(interactive (list
(read-string "value/function name: " )
(progn
(setq
param (read-string "param name (RET to finish): ")
params nil
)
(while (not (equal "" (s-trim param)))
(push (s-trim param) params)
(setq param (read-string "param name (RET to finish): "))
)
(mapconcat 'identity (reverse params) ", ")
)
(if (use-region-p) (region-beginning) (point))
(if (use-region-p) (region-end) (line-end-position))
))
(funcall 'extract-code-line-or-region-template "var " " = " nil "public void " "(" ")" " { " "}" name parameters from to)
)
(defun csharp-goto-definition (type)
"Using the higher order function and the lambda defined above, it search in the project for the definition of the input type"
(interactive (list
(read-string (format "type (%s): " (thing-at-point 'word))
nil nil (thing-at-point 'word))))
(goto-definition type csharpDefinitionRegex)
)
Use shift + arrow keys to switch between visible buffers
(windmove-default-keybindings)
Sometimes you need to see the line without breaking it
(global-set-key (kbd "C-c t t") 'toggle-truncate-lines)
(global-set-key (kbd "C-c ;") 'iedit-mode)
(global-set-key (kbd "C-k") 'crux-smart-kill-line)
(global-set-key (kbd "C-o") 'crux-smart-open-line-above)
(global-set-key (kbd "M-o") 'open-line)
(global-set-key (kbd "C-c d") 'crux-duplicate-current-line-or-region)
(global-set-key (kbd "C-x C-l") 'crux-downcase-region)
(global-set-key (kbd "C-x C-u") 'crux-upcase-region)
(global-set-key (kbd "M-c") 'upcase-initial-word)
(global-set-key [(control shift right)] (lambda () (interactive) (transpose-words 1)))
(global-set-key [(control shift left)] (lambda () (interactive) (transpose-words -1)))
(global-set-key (kbd "C-c w c") 'whitespace-cleanup)
(global-set-key (kbd "C-c w r") 'whitespace-cleanup-region)
(global-set-key (kbd "C-x 8") 'insert-char)
(global-set-key (kbd "C-c D") 'crux-delete-file-and-buffer)
(global-set-key (kbd "C-c R") 'crux-rename-file-and-buffer)
(global-set-key (kbd "C-x C-b") 'ibuffer)
(global-set-key (kbd "C-c b p") 'copy-file-name-and-path-to-kill-ring)
(global-set-key (kbd "C-c b n") 'copy-just-file-name-to-kill-ring)
(global-set-key (kbd "C-x M-k") 'kill-buffer-and-window)
(global-set-key (kbd "C-x C-M-k") 'kill-current-buffer)
(global-set-key (kbd "C-c e w") 'ediff-regions-wordwise)
(global-set-key (kbd "C-c l") #'org-store-link)
(global-set-key (kbd "C-c a") #'org-agenda)
(global-set-key (kbd "C-S-o") #'org-capture)
(global-set-key (kbd "C-c s") 'rg-project)
(global-set-key (kbd "C-c o") 'occur)
(global-unset-key (kbd "C-x f")) ;; Disable (set-fill-colmun keybinding)
(global-set-key (kbd "C-x f p") 'project-find-file)
(global-set-key (kbd "C-x f f") 'find-file)
(global-set-key (kbd "C-c f") 'indent-buffer-or-region)
(global-set-key (kbd "C-c i u") 'xah-insert-random-uuid)
(global-set-key (kbd "C-c i n") 'xah-insert-random-number)
(global-set-key (kbd "C-c i h") 'xah-insert-random-hex)
(global-set-key (kbd "C-c i s") 'xah-insert-random-string)
(global-set-key (kbd "C-c p s") 'play-sound)
(global-set-key (kbd "C-=") 'er/expand-region)
(global-set-key (kbd "C-c r f") 'crux-recentf-find-file)
(global-set-key (kbd "C-c y") 'browse-kill-ring)
Add git-link keybidings
(global-set-key (kbd "C-c g l") 'git-link)
(global-set-key (kbd "C-c /") 'comment-or-uncomment-region)
(global-set-key (kbd "C-c c f") 'format-all-region-or-buffer)
(global-set-key (kbd "C-c c s c") 'sbt-shell-clean-old-output)
(global-set-key (kbd "C-c c s e") 'scala-goto-next-warn-error)
(global-set-key (kbd "C-c c s u") 'scala-remove-unused-import)
(global-set-key (kbd "C-c c s p") 'scala-import-type-at-point)
(global-set-key (kbd "C-c c s P") 'scala-path-to-package)
(global-set-key (kbd "C-c c s x") 'scala-extract-code-line-or-region)
(global-set-key (kbd "C-c c s g") 'scala-goto-definition)
(global-set-key (kbd "C-c c s G") 'scala-github-search-open-repo)
(global-set-key (kbd "C-c c s d") 'scala-open-doc)
(global-set-key (kbd "C-c c s s") 'scala-string-to-strip-margin-string)
(global-set-key (kbd "C-c c h c") 'hs-shell-clean-old-output)
(global-set-key (kbd "C-c c h e") 'hs-goto-next-warn-error)
(global-set-key (kbd "C-c c h u") 'hs-remove-unused-import)
(global-set-key (kbd "C-c c h p") 'hs-import-type-at-point)
(global-set-key (kbd "C-c c h x") 'hs-extract-code-line-or-region)
(global-set-key (kbd "C-c c h s") 'hs-string-to-multiline-string)
(global-set-key (kbd "C-c c h d") 'hs-goto-definition)
(global-set-key (kbd "C-c c h h") 'hs-hoogle)
(global-set-key (kbd "C-c c t c") 'ts-shell-clean-old-output)
(global-set-key (kbd "C-c c t e") 'ts-goto-next-warn-error)
(global-set-key (kbd "C-c c t u") 'ts-remove-unused-import)
(global-set-key (kbd "C-c c t p") 'ts-import-type-at-point)
(global-set-key (kbd "C-c c t x") 'ts-extract-code-line-or-region)
(global-set-key (kbd "C-c c t d") 'ts-goto-definition)
(global-set-key (kbd "C-c c d c") 'csharp-shell-clean-old-output)
(global-set-key (kbd "C-c c d e") 'csharp-goto-next-warn-error)
(global-set-key (kbd "C-c c d p") 'csharp-import-type-at-point)
(global-set-key (kbd "C-c c d x") 'csharp-extract-code-line-or-region)
(global-set-key (kbd "C-c c d d") 'csharp-goto-definition)
(global-set-key (kbd "C-c c l e") 'eval-region)
(global-set-key (kbd "C-c g s") 'magit-status)
(global-set-key (kbd "C-c g i") 'magit-init)
(global-set-key (kbd "C-c g c") 'magit-clone)
(global-set-key (kbd "C-c g o") 'magit-open-repo)
(global-set-key (kbd "C-c C-s") 'shell)