Skip to content

Instantly share code, notes, and snippets.

@priyadarshan
Created April 21, 2016 12:10
Show Gist options
  • Select an option

  • Save priyadarshan/c0545bfcf6e32b3730688bd5d072e175 to your computer and use it in GitHub Desktop.

Select an option

Save priyadarshan/c0545bfcf6e32b3730688bd5d072e175 to your computer and use it in GitHub Desktop.
All the snippets from https://github.com/hatschipuh/better-helm in one place. Please refer to the original source for up-to-date code.
;;; better-helm.el
(require 'helm-config)
(helm-mode 1)
(helm-flx-mode 1)
(helm-fuzzier-mode 1)
(require 'helm-files)
(require 'helm-buffers)
;;; Apperance
;; Always pop up at bottom
(setq helm-split-window-in-side-p t)
(add-to-list 'display-buffer-alist
'("\\`\\*helm.*\\*\\'"
(display-buffer-in-side-window)
(inhibit-same-window . t)
(window-height . 0.4)))
(setq helm-swoop-split-with-multiple-windows nil
helm-swoop-split-direction 'split-window-vertically
helm-swoop-split-window-function 'helm-default-display-buffer)
;; Provide input in the header line and hide the mode-lines above
(setq helm-echo-input-in-header-line t)
(defvar bottom-buffers nil
"List of bottom buffers before helm session.
Its element is a pair of `buffer-name' and `mode-line-format'.")
(defun bottom-buffers-init ()
(setq-local mode-line-format (default-value 'mode-line-format))
(setq bottom-buffers
(cl-loop for w in (window-list)
when (window-at-side-p w 'bottom)
collect (with-current-buffer (window-buffer w)
(cons (buffer-name) mode-line-format)))))
(defun bottom-buffers-hide-mode-line ()
(setq-default cursor-in-non-selected-windows nil)
(mapc (lambda (elt)
(with-current-buffer (car elt)
(setq-local mode-line-format nil)))
bottom-buffers))
(defun bottom-buffers-show-mode-line ()
(setq-default cursor-in-non-selected-windows t)
(when bottom-buffers
(mapc (lambda (elt)
(with-current-buffer (car elt)
(setq-local mode-line-format (cdr elt))))
bottom-buffers)
(setq bottom-buffers nil)))
(defun helm-keyboard-quit-advice (orig-func &rest args)
(bottom-buffers-show-mode-line)
(apply orig-func args))
(add-hook 'helm-before-initialize-hook #'bottom-buffers-init)
(add-hook 'helm-after-initialize-hook #'bottom-buffers-hide-mode-line)
(add-hook 'helm-exit-minibuffer-hook #'bottom-buffers-show-mode-line)
(add-hook 'helm-cleanup-hook #'bottom-buffers-show-mode-line)
(advice-add 'helm-keyboard-quit :around #'helm-keyboard-quit-advice)
;; The header lines for the sources are only useful if there are more
;; then a single source. The following snippet will hide the header
;; line if there is only one.
(setq helm-display-header-line nil)
(defvar helm-source-header-default-background (face-attribute 'helm-source-header :background))
(defvar helm-source-header-default-foreground (face-attribute 'helm-source-header :foreground))
(defvar helm-source-header-default-box (face-attribute 'helm-source-header :box))
(defun helm-toggle-header-line ()
(if (> (length helm-sources) 1)
(set-face-attribute 'helm-source-header
nil
:foreground helm-source-header-default-foreground
:background helm-source-header-default-background
:box helm-source-header-default-box
:height 1.0)
(set-face-attribute 'helm-source-header
nil
:foreground (face-attribute 'helm-selection :background)
:background (face-attribute 'helm-selection :background)
:box nil
:height 0.1)))
(add-hook 'helm-before-initialize-hook 'helm-toggle-header-line)
;; hide the minibuffer while helm is active
(defun helm-hide-minibuffer-maybe ()
(when (with-helm-buffer helm-echo-input-in-header-line)
(let ((ov (make-overlay (point-min) (point-max) nil nil t)))
(overlay-put ov 'window (selected-window))
(overlay-put ov 'face (let ((bg-color (face-background 'default nil)))
`(:background ,bg-color :foreground ,bg-color)))
(setq-local cursor-type nil))))
(add-hook 'helm-minibuffer-set-up-hook 'helm-hide-minibuffer-maybe)
;;; File navigation
;; The following snippet will reconfigure the behaviour of keys in
;; helm file navigation buffers.
;; Backspace goes to the upper folder if you are not inside a
;; filename, and Return will select a file or navigate into the
;; directory if it is one.
(defun dwim-helm-find-files-up-one-level-maybe ()
(interactive)
(if (looking-back "/" 1)
(call-interactively 'helm-find-files-up-one-level)
(delete-backward-char 1)))
(define-key helm-read-file-map (kbd "<backspace>") 'dwim-helm-find-files-up-one-level-maybe)
(define-key helm-read-file-map (kbd "DEL") 'dwim-helm-find-files-up-one-level-maybe)
(define-key helm-find-files-map (kbd "<backspace>") 'dwim-helm-find-files-up-one-level-maybe)
(define-key helm-find-files-map (kbd "DEL") 'dwim-helm-find-files-up-one-level-maybe)
(defun dwim-helm-find-files-navigate-forward (orig-fun &rest args)
"Adjust how helm-execute-persistent actions behaves, depending on context"
(if (file-directory-p (helm-get-selection))
(apply orig-fun args)
(helm-maybe-exit-minibuffer)))
(define-key helm-map (kbd "<return>") 'helm-maybe-exit-minibuffer)
(define-key helm-map (kbd "RET") 'helm-maybe-exit-minibuffer)
(define-key helm-find-files-map (kbd "<return>") 'helm-execute-persistent-action)
(define-key helm-read-file-map (kbd "<return>") 'helm-execute-persistent-action)
(define-key helm-find-files-map (kbd "RET") 'helm-execute-persistent-action)
(define-key helm-read-file-map (kbd "RET") 'helm-execute-persistent-action)
(advice-add 'helm-execute-persistent-action :around #'dwim-helm-find-files-navigate-forward)
;; Remove the dots in helm file navigation
(require 'cl-lib)
(with-eval-after-load 'helm-files
(advice-add 'helm-ff-filter-candidate-one-by-one
:before-while 'no-dots-display-file-p))
(defvar no-dots-whitelist nil
"List of helm buffers in which to show dots.")
(defun no-dots-in-white-listed-helm-buffer-p ()
(member helm-buffer no-dots-whitelist))
(defun no-dots-display-file-p (file)
;; in a whitelisted buffer display the file regardless of its name
(or (no-dots-in-white-listed-helm-buffer-p)
;; not in a whitelisted buffer display all files
;; which does not end with /. /..
(not (string-match "\\(?:/\\|\\`\\)\\.\\{1,2\\}\\'" file))))
;;; Improve Flx support
;; Advice the helm source function to enable the flx fuzzy match in
;; all sources.
(defun my-helm-make-source (f &rest args)
(nconc args '(:fuzzy-match t))
(apply f args))
(advice-add 'helm-make-source :around 'my-helm-make-source)
;; increase flx speed
;; garbage collections
(defun my-minibuffer-setup-hook ()
(setq gc-cons-threshold most-positive-fixnum))
(defun my-minibuffer-exit-hook ()
(setq gc-cons-threshold 800000))
(add-hook 'minibuffer-setup-hook #'my-minibuffer-setup-hook)
(add-hook 'minibuffer-exit-hook #'my-minibuffer-exit-hook)
;;; Helm Smex
;; With the following you get helm smex with flx matching. This means
;; if you type “co” it will match company-oddmuse as the first
;; candidate. But if you choose customize-option instead it will rank
;; that command higher and next time you type “co” customize-option
;; will be the first listed match. Nice!
(require 'smex)
(require 'flx)
(add-hook 'after-init-hook (lambda () (smex-initialize)) t)
(defun helm-smex-items ()
(smex-convert-for-ido smex-cache))
(defun helm-smex-execute-command (command-name)
(unwind-protect
(execute-extended-command helm-current-prefix-arg command-name)
(smex-rank (intern command-name))))
(defvar helm-smex-source
'((name . "smex")
(candidates . helm-smex-items)
(volatile)
(match-strict identity)
(candidate-transformer . flx-helm-candidate-transformer)
(action . (("execute command" . helm-smex-execute-command)
("execute command with prefix" . helm-smex-execute-command-with-prefix)))))
(defun flx-helm-candidate-transformer (candidates)
"hairy but works"
(if (zerop (length helm-pattern))
candidates
(let* ((mp-3-patterns (helm-mm-3-get-patterns helm-pattern))
(flx-pattern (cdar mp-3-patterns))
(patterns (cons (cons 'identity
(mapconcat
#'regexp-quote
(split-string flx-pattern "" t)
".*"))
(cdr mp-3-patterns)))
res)
(setq res (loop for candidate in candidates
for matched = (loop for (predicate . regexp) in patterns
always (funcall
predicate
(string-match regexp
(helm-candidate-get-display
candidate))))
if matched
collect (let ((score (flx-score candidate flx-pattern helm-flx-cache)))
(cons (copy-sequence candidate)
(cons candidate
score)))))
(setq res (sort res
(lambda (a b)
(> (caddr a) (caddr b)))))
(helm-smex-flx-highlight-and-format res)
res)))
(defun helm-smex-flx-highlight-and-format (res)
(cl-loop for item in res
for score = (cddr item)
do
(progn
(if (string-match-p " " helm-pattern)
(cl-loop with pattern = (split-string helm-pattern)
for p in pattern
do (when (string-match (substring-no-properties p)
(substring-no-properties (car item)))
(put-text-property
(match-beginning 0) (match-end 0) 'face 'helm-match
(car item))))
(setcar item (flx-propertize (car item) score)))
(setcdr item (cadr item)))))
(defun helm-smex/run (arg)
(interactive "P")
(if arg
(smex-rebuild-cache))
(let ((helm--mode-line-display-prefarg t))
(helm :sources 'helm-smex-source
:buffer "*helm-smex*")))
(defun helm-smex-execute-command-with-prefix (command-name)
(unwind-protect
(let ((helm-current-prefix-arg (list 4)))
(execute-extended-command helm-current-prefix-arg command-name))
(smex-rank (intern command-name))))
;; I recommend using the following keybindings
(global-set-key (kbd "C-<return>") 'helm-smex/run)
(global-set-key (kbd "M-<return>") 'helm-resume)
;;; Helm adaptive
;; This will offer last choosen candidates first for more sources,
;; with support for flx.
;; I only use it to remember describe-function and describe-variable,
;; if you want to use it for other sources add them like shown below.
(with-eval-after-load 'helm-adaptive
(defcustom helm-adaptive-enabled-sources '()
"List of Helm Source names for which helm-adaptive will remember history."
:type '(repeat string)
:group 'helm-adapt)
;; Remember history for these sources add more sources here if you like
(add-to-list 'helm-adaptive-enabled-sources "describe-function")
(add-to-list 'helm-adaptive-enabled-sources "describe-variable")
;; Clobber helm's implementation
(defun helm-adapt-use-adaptive-p (&optional source-name)
"Return current source only if it use adaptive history, nil otherwise."
(when helm-adaptive-mode
(let* ((source (or source-name (helm-get-current-source)))
(adapt-source (when (listp source)
(or (assoc-default 'filtered-candidate-transformer
(assoc (assoc-default 'type source)
helm-type-attributes))
(assoc-default 'candidate-transformer
(assoc (assoc-default 'type source)
helm-type-attributes))
(assoc-default 'filtered-candidate-transformer source)
(assoc-default 'candidate-transformer source)))))
(cond
((member (cdr (assoc 'name source)) helm-adaptive-enabled-sources)
source)
((listp adapt-source)
(and (member 'helm-adaptive-sort adapt-source) source))
((eq adapt-source 'helm-adaptive-sort)
source)))))
(require 'dash)
(setq helm-fuzzy-sort-fn
(lambda (candidates source &optional use-real)
(-> candidates
(helm-flx-fuzzy-matching-sort source use-real)
(helm-adaptive-sort source)
))
helm-fuzzy-matching-highlight-fn #'helm-flx-fuzzy-highlight-match))
(helm-adaptive-mode 1)
(provide 'better-helm)
;;; better-helm.el ends here
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment