* Search: combine isearch and avy

#+begin_src emacs-lisp
  (define-key isearch-mode-map (kbd "M-j") 'avy-isearch)

#+end_src

* Global Keymap

#+begin_src emacs-lisp
  (require 'bind-key)
(bind-key* (kbd "<f1>")    #'hydra-move/body)
  (bind-key* (kbd "<f2>")    #'eshell)
  (bind-key* (kbd "<f12>")   #'toggle-viper-mode)
;;  (bind-key* (kbd "<f5>")   #'my/desc-completion-functions)

  (bind-key* (kbd "C-+")    #'er/expand-region)
(bind-key* (kbd "C--")    #'er/contract-region)
(bind-key* (kbd "M-j")    #'avy-goto-char-timer)
  (bind-key* (kbd "M-o")    #'ace-window)


  (bind-key* (kbd "C-x C-f") 'find-file)
(bind-key* (kbd "C-S-g")   'my/abort)
  (bind-key* (kbd "C-M-g")   'top-level)
(bind-key* (kbd "C-k")     'kill-line)
(bind-key* (kbd "C-S-k")   'kill-whole-line)
(bind-key* (kbd "C-.")     'embark-act)
#+end_src


#+begin_src emacs-lisp
  (bind-key* (kbd "C-c ?") #'consult-apropos)
(bind-key* (kbd "C-c G") #'rg)
(bind-key* (kbd "C-c g") #'consult-ripgrep)
  (bind-key* (kbd "C-c f") #'consult-fd)
(bind-key* (kbd "C-c b") #'consult-buffer)
  (bind-key* (kbd "C-c R") #'consult-register)
  (bind-key* (kbd "C-c l") #'consult-line)
(bind-key* (kbd "C-c s") #'consult-flyspell)
(bind-key* (kbd "C-c k") #'consult-yank-from-kill-ring)
(bind-key* (kbd "C-c e") #'dired-jump-other-window)
(bind-key* (kbd "C-c p") #'project-switch-project)

  (bind-key* (kbd "C-c C-r") #'hydra-rectangle/body)
(bind-key* (kbd "C-c C-w") #'hydra-window/body)
(bind-key* (kbd "C-c M-r") #'hydra-register/body)
(bind-key* (kbd "C-c C-b") #'hydra-bookmarks/body)
(bind-key* (kbd "C-c C-t") #'hydra-tab-bar/body)
  (bind-key* (kbd "C-c C-d") #'hydra-desktop/body)
  (bind-key* (kbd "C-c M-t") #'hydra-toggle/body)
#+end_src

** Remap Commands
... and associated keybindings.

#+begin_src emacs-lisp
  (require 'pp)
;;  (bind-key* [remap eval-last-sexp] 'pp-eval-last-sexp)
#+end_src

** On Windows only
#+begin_src emacs-lisp
  (if sys/win32p
      (progn
	(bind-key* (kbd "M-<f4>") 'run-cmd)
	)
    )
#+end_src

* Unused Keys
From the package description:
Show free bindings in current buffer.
To use, call the command free-keys. This package takes into account the major mode bindings as well as any bindings occupied by minor modes active in current buffer. If called with prefix argument C-u, you can specify a prefix map to be used, such as C-c or C-c C-x (these are specified as a string).
#+begin_src emacs-lisp
  (use-package free-keys)
#+end_src


* Hydras
see: stealfrom: centaur
better: https://github.com/abo-abo/hydra/wiki/
** Quick sort dired buffers via hydra
see basic-setup

** Dumb-Jump Hydra
An xref-Hydra may be more general and preferrable.

#+begin_src emacs-lisp
  (pretty-hydra-define hydra-dumb-jump (:color blue)
    ("Dumb Jump"
     (
      ("b" dumb-jump-back "Back")
      ("l" dumb-jump-quick-look "Quick look")
      ("j" dumb-jump-go "Go")
      ("i" dumb-jump-go-prompt "Prompt")
      ("o" dumb-jump-go-other-window "Other window")
      ("e" dumb-jump-go-prefer-external "Go external")
      ("x" dumb-jump-go-prefer-external-other-window "Go external other window")
      )
     )
    )
#+end_src


** Outline Hydra

#+begin_src emacs-lisp
  (pretty-hydra-define my/hydra-outline (:title "outline: shift code blocks"
      						:pre (my/outline-overview)
      						:post (my/outline-reset)
      						:foreign-keys warn
    						:quit-key "C-g")
    ("Move block:"
     (
      ("u" outline-move-subtree-up      "up")
      ("d" outline-move-subtree-down    "down")
      )
     "Move Cursor:"
     (
      ("j" next-line                  "next line")
      ("J" scroll-up-command          "scroll forward")
      ("k" previous-line              "previous line")
      ("K" scroll-down-command        "scroll backward")
      )
     )
    )
#+end_src


** Toggle Hydra
#+begin_src emacs-lisp
  (require 'viper)													 
(pretty-hydra-define hydra-toggle (:title "toggle features"
					  :exit t)
  (
   "Col 1:"
   (
    ("v" toggle-viper-mode            "vi-mode" )
    ("n" my/toggle-line-numbers       "line numbers (abs, rel, off)" :exit nil)
    ("w" whitespace-mode              "whitespaces" )
    ("_" subword-mode                 "subword" )
    ("p" show-paren-mode              "parenthesis" )

    ("l" global-hl-line-mode          "higlight cursor line" )
    )  
   "Col 2:"
   (
    ("t" modus-themes-toggle          "change theme")
    ("E" toggle-debug-on-error        "debug on error")  
    ("c" flyspell-mode                "spell check" )

    ("W" which-function-mode          "which function" )
    )
   )
  )
#+end_src

("s" symbol-overlay-mode "symbol")
("r" rainbow-mode "rainbow")
("d" rainbow-delimiters-mode "delimiter")
("i" highlight-indent-guides-mode "indent")
("p" smartparens-mode "smart parenthesis")

("v" global-diff-hl-mode "gutter")
("V" diff-hl-flydiff-mode "live gutter")
("M" diff-hl-margin-mode "margin gutter")
("D" diff-hl-dired-mode "dired gutter")


** Example from creator of pretty-hydra
see: https://github.com/jerrypnz/major-mode-hydra.el
(defvar jp-toggles--title (with-faicon "toggle-on" "Toggles" 1 -0.05))

(pretty-hydra-define jp-toggles
(:color amaranth :quit-key "q" :title jp-toggles--title)
("Basic"
(("n" linum-mode "line number" :toggle t)
("w" whitespace-mode "whitespace" :toggle t)
("W" whitespace-cleanup-mode "whitespace cleanup" :toggle t)
("r" rainbow-mode "rainbow" :toggle t)
("L" page-break-lines-mode "page break lines" :toggle t))
"Highlight"
(("s" symbol-overlay-mode "symbol" :toggle t)
("l" hl-line-mode "line" :toggle t)
("x" highlight-sexp-mode "sexp" :toggle t)
("t" hl-todo-mode "todo" :toggle t))
"UI"
(("d" jp-themes-toggle-light-dark "dark theme" :toggle jp-current-theme-dark-p))
"Coding"
(("p" smartparens-mode "smartparens" :toggle t)
("P" smartparens-strict-mode "smartparens strict" :toggle t)
("S" show-smartparens-mode "show smartparens" :toggle t)
("f" flycheck-mode "flycheck" :toggle t))
"Emacs"
(("D" toggle-debug-on-error "debug on error" :toggle (default-value 'debug-on-error))
("X" toggle-debug-on-quit "debug on quit" :toggle (default-value 'debug-on-quit)))))


** Windows
#+begin_src emacs-lisp
  (require 'winner)
(require 'ace-window)
#+end_src
#+begin_src emacs-lisp
  (pretty-hydra-define hydra-window (:title "Window Management"
					    :foreign-keys warn
					    :quit-key "q"
					    )
    ("Actions"
     (("o" other-window "switch")
      ("x" delete-window "delete")
      ("X" delete-other-windows "delete other windows")
      ("s" ace-swap-window "swap")
      ("a" ace-select-window "select")
      ("u" (progn
	     (winner-undo)
	     (setq this-command 'winner-undo)) "undo change")
      ("r" winner-redo "redo change")
      )
     "Resize"
     (("h"(enlarge-window-horizontally -1) "←")
      ("j"(enlarge-window-horizontally  1) "↓")
      ("k"(enlarge-window  1) "↑")
      ("l"(enlarge-window -1) "→")
      ("%" balance-windows "balance")
      ("f" toggle-frame-fullscreen "toggle fullscreen"))
     "Split"
     (("|" (lambda ()
	     (interactive)
	     (split-window-right)
	     (windmove-right)) "horizontally")
      ("-" (lambda ()
	     (interactive)
	     (split-window-below)
	     (windmove-down)) "vertically"))
     "Font size"
     (("M-+" text-scale-increase "bigger")
      ("M--" text-scale-decrease "smaller")
      ("0" (text-scale-adjust 0) "reset to default"))
     )
    )
#+end_src

** Tabbar
#+begin_src emacs-lisp
  (bind-key* (kbd "C-<right>")    #'tab-next)
(bind-key* (kbd "C-<left>")    #'tab-previous)

(defun my/bookmark-jump-other-tab (bookmark)
  "Jump to BOOKMARK in another tab. See `bookmark-jump' for more."
  (interactive
   (bookmark-jump bookmark 'switch-to-buffer-other-tab))
  )

(pretty-hydra-define hydra-tab-bar (:title "Tab Bar Operations"
					   :foreign-keys warn
					   :quit-key "q")
  ("Creation"
   (("t" (switch-to-buffer-other-tab "*Bookmark List*") "Create a new tab")
    ("d" dired-other-tab "Open Dired in another tab")
    ("f" find-file-other-tab "Find file in another tab")
    ("x" tab-window-detach "move window to tab")
    ("0" tab-close "Close current tab")
    )
   "Management"
   (("m" tab-move "Move current tab")
    ("r" tab-rename "Rename Tab")
    )
   )
  )
#+end_src

** Desktop Hydra
#+begin_src emacs-lisp
  (pretty-hydra-define hydra-desktop (:title "Desktop Operations"
					     :color blue)
    ("Load/Save"
     (
      ("l" desktop-read "load default desktop")
      ("s" desktop-save "save")
      ("b" bmkp-set-desktop-bookmark "save as bookmark")
      )
     "Misc"
     (
      ("c" desktop-clear "clear")
      ("d" desktop-change-dir "dir")
      ("r" desktop-revert "revert")
      )
     )
    )
#+end_src

** Rectangle
#+begin_src emacs-lisp
  (defun my/ex-point-mark ()
    (interactive)
    (if rectangle-mark-mode
	(exchange-point-and-mark)
      (let ((mk (mark)))
	(rectangle-mark-mode 1)
	(goto-char mk))))

(defun my/reset-rectangle ()
  (interactive)
  (if (region-active-p)
      (progn
	(rectangle-exchange-point-and-mark)
	(deactivate-mark)
	)
    )
  (rectangle-mark-mode 1)
  )

(pretty-hydra-define hydra-rectangle (
				      :title "Rectangle Editing"
				      :foreign-keys run
				      :pre (rectangle-mark-mode 1)
				      :post (deactivate-mark)
				      :quit-key "q"
				      )
  (
   "Select" (
	     ("h" rectangle-backward-char "left")
	     ("l" rectangle-forward-char "right")
	     ("k" rectangle-previous-line "up")
	     ("j" rectangle-next-line "down")
	     ("e" my/ex-point-mark "exchange mark with point")
	     )
   "Act" (
	  ("p" kill-rectangle "kill")
	  ("c" copy-rectangle-as-kill "copy")
	  ("R" copy-rectangle-to-register "copy to register")
	  ("y" yank-rectangle "yank" :color blue)
	  ("s" string-rectangle "type to replace")
	  )
   "Undo ..." (
	       ("x" my/reset-rectangle "reset and start again")
	       ("u" undo "undo")
	       ("r" redo "redo")
	       )
   )
  )
#+end_src

** TODO Registers
#+begin_src emacs-lisp
  (pretty-hydra-define hydra-registers (:title "Register commands" :color blue :hint nil)
    ("store"
     (
      ("s" point-to-register "save point" :exit t)
      ("y" copy-to-register "save in r.." :exit t)
      ("n" number-to-register "save number in r.." :exit t)
      ("w" window-configuration-to-register "save window config in r.." :exit t)
      )
     "Other commands"
     (
      ("l" list-registers "show register content")
      ("+" increment-register "increment number" :exit t)
      ("j" jump-to-register "jump to register" :exit t)
      ("p" insert-register "insert from r.." :exit t)
      )
     )
    )
#+end_src

** Completion Hydra
#+begin_src emacs-lisp
  (pretty-hydra-define hydra-complete (:title "complete" :exit t)
    ("Abbreviation" (
  		     ("/" cape-dabbrev "dynamic abbreviation")
                     ("w" cape-dict "dictionary")
  		     )
     "Symbol" (
  	       ("t" complete-tag "complete tag")
  	       ("s" cape-lisp-symbol "symbol")
  	       ("\\" cape-tex "tex symbol")
  	       ("&" cape-sgml "sgml symbol")
  	       ("r" cape-rfc1345 "symbol defined in RFC1345")
  	       )
     "Others" (
  	       ("h" cape-history "from history")
  	       ("f" cape-file "filename")
  	       )
     )
    )
#+end_src

** Movement Hydra
#+begin_src emacs-lisp
  (pretty-hydra-define hydra-move (:title "move"
  					  :foreign-keys warn
  					  :quit-key "q")
    (
     "avy" (
            ("j" avy-goto-char-timer  "goto char")
  	    ("n" avy-next "avy next")
  	    ("p" avy-prev "avy prev")
  	    )
     "forward" (
  		(">" end-of-buffer  "last line")
  		("$" end-of-line    "EOL")
  		("}" forward-paragraph  "paragraph")
  		("s" forward-sentence   "sentence")
  		("l" next-logical-line  "line")
  		("w" viper-forward-word "word")
  		("p" scroll-down  "page")
  		)
     "backward" (
  		 ("<" beginning-of-buffer "first line")
  		 ("0" beginning-of-line "beginning of line")
  		 ("{" backward-paragraph "paragraph")
  		 ("S" backward-sentence   "sentence")
  		 ("L" previous-logical-line  "line")
  		 ("W" viper-backward-word "word")
  		 ("P" scroll-up "page")
  		 )
     "Others" (
  	       ("|" move-to-column "→ column")
  	       (":" goto-line      "→ line")
  	       ("%" recenter       "center display around cursor")
  	       )
     "Exit"   (
  	       ("i" nil            "insert-mode" :exit t)
  	       ("a" forward-char      "append-mode" :exit t)
  	       ("o" viper-open-line "open line below" :exit t)
  	       ("O" viper-Open-line "open line above" :exit t)
  	       )
     )
    )
#+end_src

** Unicode
#+begin_src emacs-lisp
  (defun my/insert-unicode (unicode-name)
    "Same as: C-x 8 Enter UNICODE-NAME."
    (insert-char (gethash unicode-name (ucs-names))))
(pretty-hydra-define hydra-unicode (:title "Unicode" :exit t)
  ("Sets" (
	   ("N" (insert-char 8469) "ℕ") ;; natural numbers
	   ("R" (insert-char 8477) "ℝ") ;; real numbers
	   ("Z" (insert-char 8484) "ℤ") ;; real numbers
	   )
   "Operators" (
		("e" (insert-char 948) "∈")
		("a" (my/insert-unicode "ALMOST EQUAL TO") "≈")
		("p" (insert-char 8706) "∂ (partial diff)")
		)
   "Statistics" (
		 ("m" (my/insert-unicode "MICRO SIGN") "µ")
		 ("s" (insert-char 963) "σ")
		 ("v" (progn (insert-char 963)(insert-char 178)) "σ²")
		 )
   "Letters" (
	      ("d" (my/insert-unicode "GREEK SMALL LETTER DELTA") "δ")
	      )
   "Misc" (
	   ("o" (my/insert-unicode "DEGREE SIGN") "°")
	   ("E" (my/insert-unicode "EURO SIGN") "€")
	   (">" (my/insert-unicode "RIGHTWARDS ARROW") "→")
	   )
   )
  )
#+end_src

** Websearch
stolen from aboabo and adapted
#+begin_src emacs-lisp
  (defun ora-search-query (fmt)
    (let ((query (if (region-active-p)
                     (buffer-substring-no-properties (region-beginning) (region-end))
                   (read-from-minibuffer "Search for: "))))
      (browse-url (format fmt query))))

(defhydra hydra-web-search (:exit t)
  ("w" (ora-search-query "https://en.wikipedia.org/w/index.php?search=%s") "wiki")
  ("g" (ora-search-query "https://github.com/search?ref=simplesearch&q=%s") "github")
  ("m" (ora-search-query "https://www.google.com/maps/search/%s?hl=en&source=opensearch") "maps")
  ("r" (ora-search-query "https://www.reddit.com/search?q=%s") "reddit")
  ("y" (ora-search-query "https://www.youtube.com/results?search_query=%s&page={startPage?}&utm_source=opensearch") "youtube")
  ("SPC" nil "quit"))
#+end_src

* TODO Project

Exchange projectile commands for project commands

#+begin_src emacs-lisp
  
#+end_src

(defvar hydra-project--title (with-faicon "balance-scale" "Project" 1 -0.05))
(pretty-hydra-define hydra-project
(:color blue :quit-key ("q" "SPC") :title hydra-project--title)
("Actions"
(("s" projectile-switch-open-project "switch open project")
("S" projectile-switch-project "switch project")
("i" projectile-project-info "info")
("a" projectile-add-known-project "add")
("k" projectile-remove-known-project "remove")
("r" projectile-find-references "find references")
("f" projectile-find-file "find file")
("v" projectile-shell "vterm")
("d" projectile-discover-projects-in-directory "discover new projects")
("c" projectile-comander "help (commander)"))))


* TODO Denote
let ((map global-map))
(define-key map (kbd "C-c n j") #'my-denote-journal) ; our custom command
(define-key map (kbd "C-c n n") #'denote)
(define-key map (kbd "C-c n N") #'denote-type)
(define-key map (kbd "C-c n d") #'denote-date)
(define-key map (kbd "C-c n i") #'denote-link) ; "insert" mnemonic
(define-key map (kbd "C-c n r") #'denote-rename-file)
(define-key map (kbd "C-c n R") #'denote-rename-file-using-front-matter))
;; Key bindings specifically for Dired.
let ((map dired-mode-map))
(define-key map (kbd "C-c C-d C-i") #'denote-link-dired-marked-notes)
(define-key map (kbd "C-c C-d C-r") #'denote-dired-rename-marked-files)
(define-key map (kbd "C-c C-d C-R") #'denote-dired-rename-marked-files-using-front-matter))

* Bye
#+begin_src emacs-lisp
;;; keybindings.el ends here
#+end_src