2016-04-29 21:48:00 +00:00
|
|
|
;;; funcs.el --- Shell Layer functions File
|
2016-02-02 15:42:58 +00:00
|
|
|
;;
|
2021-03-22 20:11:29 +00:00
|
|
|
;; Copyright (c) 2012-2021 Sylvain Benner & Contributors
|
2016-02-02 15:42:58 +00:00
|
|
|
;;
|
|
|
|
;; Author: Sylvain Benner <sylvain.benner@gmail.com>
|
|
|
|
;; URL: https://github.com/syl20bnr/spacemacs
|
|
|
|
;;
|
|
|
|
;; This file is not part of GNU Emacs.
|
|
|
|
;;
|
2021-03-24 03:31:44 +00:00
|
|
|
;; This program is free software; you can redistribute it and/or modify
|
|
|
|
;; it under the terms of the GNU General Public License as published by
|
|
|
|
;; the Free Software Foundation, either version 3 of the License, or
|
|
|
|
;; (at your option) any later version.
|
|
|
|
;;
|
|
|
|
;; This program is distributed in the hope that it will be useful,
|
|
|
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
;; GNU General Public License for more details.
|
|
|
|
;;
|
|
|
|
;; You should have received a copy of the GNU General Public License
|
|
|
|
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
2016-02-02 15:42:58 +00:00
|
|
|
|
|
|
|
(defun spacemacs/projectile-shell-pop ()
|
|
|
|
"Open a term buffer at projectile project root."
|
|
|
|
(interactive)
|
|
|
|
(let ((default-directory (projectile-project-root)))
|
|
|
|
(call-interactively 'spacemacs/default-pop-shell)))
|
2016-02-27 23:25:33 +00:00
|
|
|
|
|
|
|
(defun spacemacs/disable-hl-line-mode ()
|
|
|
|
"Locally disable global-hl-line-mode"
|
|
|
|
(interactive)
|
|
|
|
(setq-local global-hl-line-mode nil))
|
2016-04-06 12:41:19 +00:00
|
|
|
|
|
|
|
(defun spacemacs/init-eshell-xterm-color ()
|
|
|
|
"Initialize xterm coloring for eshell"
|
|
|
|
(setq-local xterm-color-preserve-properties t)
|
|
|
|
(make-local-variable 'eshell-preoutput-filter-functions)
|
|
|
|
(add-hook 'eshell-preoutput-filter-functions 'xterm-color-filter)
|
|
|
|
(setq-local eshell-output-filter-functions
|
|
|
|
(remove 'eshell-handle-ansi-color
|
|
|
|
eshell-output-filter-functions)))
|
2016-04-07 18:52:41 +00:00
|
|
|
|
|
|
|
(defun ansi-term-handle-close ()
|
|
|
|
"Close current term buffer when `exit' from term buffer."
|
|
|
|
(when (ignore-errors (get-buffer-process (current-buffer)))
|
|
|
|
(set-process-sentinel (get-buffer-process (current-buffer))
|
|
|
|
(lambda (proc change)
|
|
|
|
(when (string-match "\\(finished\\|exited\\)"
|
|
|
|
change)
|
|
|
|
(kill-buffer (process-buffer proc))
|
2019-05-19 23:09:14 +00:00
|
|
|
(when (and close-window-with-terminal
|
|
|
|
(> (count-windows) 1))
|
2016-04-07 18:52:41 +00:00
|
|
|
(delete-window)))))))
|
|
|
|
|
|
|
|
(defun spacemacs/default-pop-shell ()
|
|
|
|
"Open the default shell in a popup."
|
|
|
|
(interactive)
|
2019-12-18 08:58:56 +00:00
|
|
|
(let ((shell (cl-case shell-default-shell
|
2018-10-11 14:51:02 +00:00
|
|
|
('multi-term 'multiterm)
|
|
|
|
('shell 'inferior-shell)
|
2018-10-13 10:05:27 +00:00
|
|
|
(t shell-default-shell))))
|
2016-04-07 18:52:41 +00:00
|
|
|
(call-interactively (intern (format "spacemacs/shell-pop-%S" shell)))))
|
|
|
|
|
2018-01-22 19:55:21 +00:00
|
|
|
(defun spacemacs/resize-shell-to-desired-width ()
|
2018-07-18 05:38:29 +00:00
|
|
|
(when (and (string= (buffer-name) shell-pop-last-shell-buffer-name)
|
|
|
|
(memq shell-pop-window-position '(left right)))
|
|
|
|
(enlarge-window-horizontally (- (/ (* (frame-width) shell-default-width)
|
|
|
|
100)
|
|
|
|
(window-width)))))
|
2018-01-22 19:55:21 +00:00
|
|
|
|
2018-11-05 14:27:32 +00:00
|
|
|
(defmacro make-shell-pop-command (name func &optional shell)
|
2016-04-07 18:52:41 +00:00
|
|
|
"Create a function to open a shell via the function FUNC.
|
|
|
|
SHELL is the SHELL function to use (i.e. when FUNC represents a terminal)."
|
2018-11-05 14:27:32 +00:00
|
|
|
`(defun ,(intern (concat "spacemacs/shell-pop-" name)) (index)
|
|
|
|
,(format (concat "Toggle a popup window with `%S'.\n"
|
|
|
|
"Multiple shells can be opened with a numerical prefix "
|
|
|
|
"argument. Using the universal prefix argument will "
|
|
|
|
"open the shell in the current buffer instead of a "
|
|
|
|
"popup buffer.")
|
|
|
|
func)
|
|
|
|
(interactive "P")
|
|
|
|
(require 'shell-pop)
|
|
|
|
(if (equal '(4) index)
|
|
|
|
;; no popup
|
|
|
|
(,func ,shell)
|
2020-06-25 23:10:17 +00:00
|
|
|
(shell-pop--set-shell-type
|
2018-11-05 14:27:32 +00:00
|
|
|
'shell-pop-shell-type
|
2018-03-08 17:17:17 +00:00
|
|
|
(list ,name
|
2020-06-25 23:10:17 +00:00
|
|
|
,(if (bound-and-true-p layouts-enable-local-variables)
|
|
|
|
`(concat "*" (spacemacs//current-layout-name) "-"
|
2018-03-08 17:17:17 +00:00
|
|
|
(if (file-remote-p default-directory)
|
|
|
|
"remote-"
|
2020-06-25 23:10:17 +00:00
|
|
|
"")
|
2018-03-08 17:17:17 +00:00
|
|
|
,name "*")
|
2020-06-25 23:10:17 +00:00
|
|
|
(concat "*" name "*"))
|
|
|
|
(lambda nil (,func ,shell))))
|
2018-11-05 14:27:32 +00:00
|
|
|
(shell-pop index)
|
|
|
|
(spacemacs/resize-shell-to-desired-width))))
|
2016-05-30 13:11:43 +00:00
|
|
|
|
|
|
|
(defun projectile-multi-term-in-root ()
|
|
|
|
"Invoke `multi-term' in the project's root."
|
|
|
|
(interactive)
|
|
|
|
(projectile-with-default-dir (projectile-project-root) (multi-term)))
|
2016-08-17 19:00:16 +00:00
|
|
|
|
|
|
|
(defun spacemacs//toggle-shell-auto-completion-based-on-path ()
|
|
|
|
"Deactivates automatic completion on remote paths.
|
|
|
|
Retrieving completions for Eshell blocks Emacs. Over remote
|
|
|
|
connections the delay is often annoying, so it's better to let
|
|
|
|
the user activate the completion manually."
|
|
|
|
(if (file-remote-p default-directory)
|
|
|
|
(setq-local company-idle-delay nil)
|
2018-05-23 04:27:08 +00:00
|
|
|
(setq-local company-idle-delay auto-completion-idle-delay)))
|
2016-08-17 19:00:16 +00:00
|
|
|
|
|
|
|
(defun spacemacs//eshell-switch-company-frontend ()
|
|
|
|
"Sets the company frontend to `company-preview-frontend' in e-shell mode."
|
2017-08-11 17:15:07 +00:00
|
|
|
(require 'company)
|
2016-08-17 19:00:16 +00:00
|
|
|
(setq-local company-frontends '(company-preview-frontend)))
|
|
|
|
|
|
|
|
(defun spacemacs//eshell-auto-end ()
|
|
|
|
"Move point to end of current prompt when switching to insert state."
|
|
|
|
(when (and (eq major-mode 'eshell-mode)
|
|
|
|
;; Not on last line, we might want to edit within it.
|
2020-02-09 01:36:01 +00:00
|
|
|
(not (>= (point) eshell-last-output-end))
|
2018-06-17 20:00:51 +00:00
|
|
|
;; Not on the last sent command if we use smart-eshell so we can
|
|
|
|
;; edit it.
|
|
|
|
(not (and shell-enable-smart-eshell
|
|
|
|
(>= (point) eshell-last-input-start)
|
|
|
|
(< (point) eshell-last-input-end))))
|
2016-08-17 19:00:16 +00:00
|
|
|
(end-of-buffer)))
|
|
|
|
|
|
|
|
(defun spacemacs//protect-eshell-prompt ()
|
|
|
|
"Protect Eshell's prompt like Comint's prompts.
|
|
|
|
|
|
|
|
E.g. `evil-change-whole-line' won't wipe the prompt. This
|
|
|
|
is achieved by adding the relevant text properties."
|
|
|
|
(let ((inhibit-field-text-motion t))
|
|
|
|
(add-text-properties
|
|
|
|
(point-at-bol)
|
|
|
|
(point)
|
|
|
|
'(rear-nonsticky t
|
|
|
|
inhibit-line-move-field-capture t
|
|
|
|
field output
|
|
|
|
read-only t
|
|
|
|
front-sticky (field inhibit-line-move-field-capture)))))
|
|
|
|
|
|
|
|
(defun spacemacs//init-eshell ()
|
|
|
|
"Stuff to do when enabling eshell."
|
|
|
|
(setq pcomplete-cycle-completions nil)
|
|
|
|
(if (bound-and-true-p linum-mode) (linum-mode -1))
|
2018-06-17 20:00:51 +00:00
|
|
|
;; autojump to prompt line if not on one already
|
|
|
|
(add-hook 'evil-insert-state-entry-hook
|
|
|
|
'spacemacs//eshell-auto-end nil t)
|
|
|
|
(add-hook 'evil-hybrid-state-entry-hook
|
|
|
|
'spacemacs//eshell-auto-end nil t)
|
2017-07-02 13:48:06 +00:00
|
|
|
(when (configuration-layer/package-used-p 'semantic)
|
2016-08-17 19:00:16 +00:00
|
|
|
(semantic-mode -1))
|
2017-03-12 23:45:07 +00:00
|
|
|
;; This is an eshell alias
|
|
|
|
(defun eshell/clear ()
|
|
|
|
(let ((inhibit-read-only t))
|
|
|
|
(erase-buffer)))
|
|
|
|
;; This is a key-command
|
|
|
|
(defun spacemacs/eshell-clear-keystroke ()
|
|
|
|
"Allow for keystrokes to invoke eshell/clear"
|
|
|
|
(interactive)
|
|
|
|
(eshell/clear)
|
|
|
|
(eshell-send-input))
|
2016-08-17 19:00:16 +00:00
|
|
|
;; Caution! this will erase buffer's content at C-l
|
2017-03-12 23:45:07 +00:00
|
|
|
(define-key eshell-mode-map (kbd "C-l") 'spacemacs/eshell-clear-keystroke)
|
2018-02-11 12:27:16 +00:00
|
|
|
(define-key eshell-mode-map (kbd "C-d") 'eshell-delchar-or-maybe-eof)
|
2017-03-12 23:45:07 +00:00
|
|
|
|
2018-02-11 12:27:16 +00:00
|
|
|
;; These don't work well in normal state
|
|
|
|
;; due to evil/emacs cursor incompatibility
|
|
|
|
(evil-define-key 'insert eshell-mode-map
|
|
|
|
(kbd "C-k") 'eshell-previous-matching-input-from-input
|
|
|
|
(kbd "C-j") 'eshell-next-matching-input-from-input))
|
2016-08-17 19:00:16 +00:00
|
|
|
|
|
|
|
(defun spacemacs/helm-eshell-history ()
|
|
|
|
"Correctly revert to insert state after selection."
|
|
|
|
(interactive)
|
|
|
|
(helm-eshell-history)
|
|
|
|
(evil-insert-state))
|
|
|
|
|
|
|
|
(defun spacemacs/helm-shell-history ()
|
|
|
|
"Correctly revert to insert state after selection."
|
|
|
|
(interactive)
|
|
|
|
(helm-comint-input-ring)
|
|
|
|
(evil-insert-state))
|
|
|
|
|
|
|
|
(defun spacemacs/init-helm-eshell ()
|
|
|
|
"Initialize helm-eshell."
|
2019-05-07 23:31:03 +00:00
|
|
|
(define-key eshell-mode-map (kbd "<tab>") 'helm-esh-pcomplete)
|
2016-08-17 19:00:16 +00:00
|
|
|
(spacemacs/set-leader-keys-for-major-mode 'eshell-mode
|
|
|
|
"H" 'spacemacs/helm-eshell-history)
|
|
|
|
(define-key eshell-mode-map
|
|
|
|
(kbd "M-l") 'spacemacs/helm-eshell-history))
|
|
|
|
|
2019-05-08 21:10:08 +00:00
|
|
|
(defun spacemacs/ivy-eshell-history ()
|
|
|
|
(interactive)
|
|
|
|
(counsel-esh-history)
|
|
|
|
(evil-insert-state))
|
|
|
|
|
|
|
|
(defun spacemacs/pcomplete-std-complete ()
|
|
|
|
(interactive)
|
|
|
|
(pcomplete-std-complete)
|
|
|
|
(evil-insert-state))
|
|
|
|
|
|
|
|
(defun spacemacs/init-ivy-eshell ()
|
|
|
|
"Initialize ivy-eshell."
|
|
|
|
(spacemacs/set-leader-keys-for-major-mode 'eshell-mode
|
|
|
|
"H" #'spacemacs/ivy-eshell-history)
|
|
|
|
(define-key eshell-mode-map (kbd "M-l") #'spacemacs/ivy-eshell-history)
|
|
|
|
(define-key eshell-mode-map (kbd "<tab>") #'spacemacs/pcomplete-std-complete))
|
|
|
|
|
2018-10-11 14:51:02 +00:00
|
|
|
(defun term-send-tab ()
|
|
|
|
"Send tab in term mode."
|
|
|
|
(interactive)
|
|
|
|
(term-send-raw-string "\t"))
|
|
|
|
|
|
|
|
;; Wrappers for non-standard shell commands
|
|
|
|
(defun multiterm (&optional ARG)
|
2016-08-17 19:00:16 +00:00
|
|
|
"Wrapper to be able to call multi-term from shell-pop"
|
|
|
|
(interactive)
|
|
|
|
(multi-term))
|
|
|
|
|
2018-10-11 14:51:02 +00:00
|
|
|
(defun inferior-shell (&optional ARG)
|
|
|
|
"Wrapper to open shell in current window"
|
2016-08-17 19:00:16 +00:00
|
|
|
(interactive)
|
2018-10-11 14:51:02 +00:00
|
|
|
(switch-to-buffer "*shell*")
|
|
|
|
(shell "*shell*"))
|
2018-11-05 16:43:27 +00:00
|
|
|
|
|
|
|
;; https://stackoverflow.com/questions/6837511/automatically-disable-a-global-minor-mode-for-a-specific-major-mode
|
|
|
|
(defun spacemacs//inhibit-global-centered-cursor-mode ()
|
|
|
|
"Counter-act `global-centered-cursor-mode'."
|
|
|
|
(add-hook 'after-change-major-mode-hook
|
|
|
|
(lambda ()
|
|
|
|
(centered-cursor-mode 0))
|
|
|
|
:append
|
|
|
|
:local))
|
2018-03-17 17:42:54 +00:00
|
|
|
|
|
|
|
(defun spacemacs//shell-pop-restore-window ()
|
|
|
|
"Fixes an issue during `shell-pop-out' where it
|
|
|
|
tries to restore a dead buffer or window."
|
|
|
|
(unless (buffer-live-p shell-pop-last-buffer)
|
|
|
|
(setq shell-pop-last-buffer (window-buffer (get-mru-window nil t t))))
|
|
|
|
(unless (window-live-p shell-pop-last-window)
|
|
|
|
(setq shell-pop-last-window (get-buffer-window shell-pop-last-buffer))))
|
2020-10-05 21:19:39 +00:00
|
|
|
|
|
|
|
(defun spacemacs//vterm-make-history-candidates ()
|
|
|
|
(with-temp-buffer
|
|
|
|
(insert-file-contents spacemacs-vterm-history-file-location)
|
|
|
|
(reverse
|
|
|
|
(delete-dups
|
|
|
|
(split-string (buffer-string) "\n")))))
|
|
|
|
|
|
|
|
(defun spacemacs/helm-vterm-search-history ()
|
|
|
|
"Narrow down bash history with helm."
|
|
|
|
(interactive)
|
2020-10-31 03:44:53 +00:00
|
|
|
(assert (string-equal mode-name "VTerm") nil "Not in VTerm mode")
|
2020-10-05 21:19:39 +00:00
|
|
|
(helm :sources (helm-build-sync-source "Bash history"
|
|
|
|
:candidates (spacemacs//vterm-make-history-candidates)
|
|
|
|
:action #'vterm-send-string)
|
|
|
|
:buffer "*helm-bash-history*"
|
|
|
|
:candidate-number-limit 10000))
|
|
|
|
|
|
|
|
(defun spacemacs/counsel-vterm-search-history ()
|
|
|
|
"Narrow down bash history with ivy."
|
|
|
|
(interactive)
|
|
|
|
(assert (string-equal mode-name "VTerm") nil "Not in VTerm mode")
|
|
|
|
(ivy-read "Bash history: "
|
|
|
|
(spacemacs//vterm-make-history-candidates)
|
|
|
|
:keymap counsel-describe-map
|
|
|
|
:preselect (ivy-thing-at-point)
|
|
|
|
:history 'spacemacs/counsel-shell-search-history-history
|
|
|
|
:require-match t
|
|
|
|
:action #'vterm-send-string
|
|
|
|
:caller 'spacemacs/counsel-vterm-search-history))
|
|
|
|
|
|
|
|
(defun spacemacs//vterm-bind-m-r (mode-map)
|
|
|
|
(cond
|
|
|
|
((configuration-layer/layer-used-p 'helm)
|
|
|
|
(define-key mode-map (kbd "M-r") 'spacemacs/helm-vterm-search-history))
|
|
|
|
((configuration-layer/layer-used-p 'ivy)
|
|
|
|
(define-key mode-map (kbd "M-r") 'spacemacs/counsel-vterm-search-history))))
|