2015-01-27 03:51:47 +00:00
|
|
|
|
;;; core-funcs.el --- Spacemacs Core File
|
2015-01-27 03:39:14 +00:00
|
|
|
|
;;
|
2020-09-16 21:34:40 +00:00
|
|
|
|
;; Copyright (c) 2012-2020 Sylvain Benner & Contributors
|
2015-01-27 03:39:14 +00:00
|
|
|
|
;;
|
|
|
|
|
;; Author: Sylvain Benner <sylvain.benner@gmail.com>
|
|
|
|
|
;; URL: https://github.com/syl20bnr/spacemacs
|
|
|
|
|
;;
|
|
|
|
|
;; This file is not part of GNU Emacs.
|
|
|
|
|
;;
|
|
|
|
|
;;; License: GPLv3
|
2015-09-26 04:26:16 +00:00
|
|
|
|
|
2015-12-16 15:10:26 +00:00
|
|
|
|
(defvar configuration-layer--protected-packages)
|
|
|
|
|
(defvar dotspacemacs-filepath)
|
2016-01-13 20:47:07 +00:00
|
|
|
|
(defvar spacemacs-repl-list '()
|
|
|
|
|
"List of all registered REPLs.")
|
2015-12-16 15:10:26 +00:00
|
|
|
|
|
2018-06-08 06:20:47 +00:00
|
|
|
|
(defmacro spacemacs|dotspacemacs-backward-compatibility (variable default)
|
|
|
|
|
"Return `if' sexp for backward compatibility with old dotspacemacs
|
|
|
|
|
values."
|
|
|
|
|
`(if (boundp ',variable) ,variable ',default))
|
|
|
|
|
|
2016-03-31 04:33:56 +00:00
|
|
|
|
(defun spacemacs/system-is-mac ()
|
|
|
|
|
(eq system-type 'darwin))
|
|
|
|
|
(defun spacemacs/system-is-linux ()
|
|
|
|
|
(eq system-type 'gnu/linux))
|
|
|
|
|
(defun spacemacs/system-is-mswindows ()
|
|
|
|
|
(eq system-type 'windows-nt))
|
2016-03-31 04:34:28 +00:00
|
|
|
|
|
|
|
|
|
(defun spacemacs/window-system-is-mac ()
|
|
|
|
|
;; ns is returned instead of mac on Emacs 25+
|
|
|
|
|
(memq (window-system) '(mac ns)))
|
|
|
|
|
|
2018-06-07 10:13:06 +00:00
|
|
|
|
(defun spacemacs/mplist-get-values (plist prop)
|
2015-01-27 03:39:14 +00:00
|
|
|
|
"Get the values associated to PROP in PLIST, a modified plist.
|
|
|
|
|
|
|
|
|
|
A modified plist is one where keys are keywords and values are
|
|
|
|
|
all non-keywords elements that follow it.
|
|
|
|
|
|
|
|
|
|
If there are multiple properties with the same keyword, only the first property
|
|
|
|
|
and its values is returned.
|
|
|
|
|
|
|
|
|
|
Currently this function infloops when the list is circular."
|
|
|
|
|
(let ((tail plist)
|
|
|
|
|
result)
|
|
|
|
|
(while (and (consp tail) (not (eq prop (car tail))))
|
|
|
|
|
(pop tail))
|
|
|
|
|
;; pop the found keyword
|
|
|
|
|
(pop tail)
|
|
|
|
|
(while (and (consp tail) (not (keywordp (car tail))))
|
|
|
|
|
(push (pop tail) result))
|
|
|
|
|
(nreverse result)))
|
|
|
|
|
|
2018-06-07 10:13:06 +00:00
|
|
|
|
(defun spacemacs/mplist-get-value (plist prop)
|
|
|
|
|
"Get a single value associated to PROP in PLIST, a modified plist.
|
2018-06-04 05:19:44 +00:00
|
|
|
|
|
2018-06-07 04:55:37 +00:00
|
|
|
|
You should always use this function instead of builtin `plist-get'
|
2018-06-04 05:19:44 +00:00
|
|
|
|
in Spacemacs.
|
|
|
|
|
|
|
|
|
|
A modified plist is one where keys are keywords and values are
|
|
|
|
|
all non-keywords elements that follow it.
|
|
|
|
|
|
|
|
|
|
If there are multiple properties with the same keyword, only the first property
|
|
|
|
|
and its values is returned.
|
|
|
|
|
|
|
|
|
|
Currently this function infloops when the list is circular."
|
2018-06-07 10:13:06 +00:00
|
|
|
|
(car (spacemacs/mplist-get-values plist prop)))
|
2018-06-04 05:19:44 +00:00
|
|
|
|
|
2015-01-27 03:39:14 +00:00
|
|
|
|
(defun spacemacs/mplist-remove (plist prop)
|
|
|
|
|
"Return a copy of a modified PLIST without PROP and its values.
|
|
|
|
|
|
|
|
|
|
If there are multiple properties with the same keyword, only the first property
|
|
|
|
|
and its values are removed."
|
|
|
|
|
(let ((tail plist)
|
|
|
|
|
result)
|
|
|
|
|
(while (and (consp tail) (not (eq prop (car tail))))
|
|
|
|
|
(push (pop tail) result))
|
|
|
|
|
(when (eq prop (car tail))
|
|
|
|
|
(pop tail)
|
|
|
|
|
(while (and (consp tail) (not (keywordp (car tail))))
|
|
|
|
|
(pop tail)))
|
|
|
|
|
(while (consp tail)
|
|
|
|
|
(push (pop tail) result))
|
|
|
|
|
(nreverse result)))
|
|
|
|
|
|
2016-05-02 17:09:18 +00:00
|
|
|
|
;; Originally based on http://stackoverflow.com/questions/2321904/elisp-how-to-save-data-in-a-file
|
2015-02-04 04:56:38 +00:00
|
|
|
|
(defun spacemacs/dump-vars-to-file (varlist filename)
|
|
|
|
|
"simplistic dumping of variables in VARLIST to a file FILENAME"
|
2016-05-02 17:09:18 +00:00
|
|
|
|
(with-temp-file filename
|
2018-05-06 03:05:36 +00:00
|
|
|
|
(spacemacs/dump-vars varlist (current-buffer))
|
2016-05-02 17:09:18 +00:00
|
|
|
|
(make-directory (file-name-directory filename) t)))
|
2015-02-04 04:56:38 +00:00
|
|
|
|
|
|
|
|
|
;; From http://stackoverflow.com/questions/2321904/elisp-how-to-save-data-in-a-file
|
2018-05-06 03:05:36 +00:00
|
|
|
|
(defun spacemacs/dump-vars (varlist buffer)
|
2015-02-04 04:56:38 +00:00
|
|
|
|
"insert into buffer the setq statement to recreate the variables in VARLIST"
|
2015-10-05 07:22:35 +00:00
|
|
|
|
(cl-loop for var in varlist do
|
2019-07-31 04:34:51 +00:00
|
|
|
|
(print (list 'setq var (list 'quote (symbol-value var)))
|
|
|
|
|
buffer)))
|
2015-02-04 04:56:38 +00:00
|
|
|
|
|
2015-02-16 02:25:12 +00:00
|
|
|
|
(defvar spacemacs--init-redisplay-count 0
|
|
|
|
|
"The number of calls to `redisplay'")
|
|
|
|
|
(defun spacemacs//redisplay ()
|
|
|
|
|
"`redisplay' wrapper."
|
|
|
|
|
(setq spacemacs--init-redisplay-count (1+ spacemacs--init-redisplay-count))
|
2019-08-22 03:30:55 +00:00
|
|
|
|
(force-window-update)
|
2015-02-16 02:25:12 +00:00
|
|
|
|
(redisplay))
|
|
|
|
|
|
2015-02-24 04:28:23 +00:00
|
|
|
|
(defun spacemacs//create-key-binding-form (props func)
|
|
|
|
|
"Helper which returns a from to bind FUNC to a key according to PROPS.
|
|
|
|
|
|
|
|
|
|
Supported properties:
|
|
|
|
|
|
|
|
|
|
`:evil-leader STRING'
|
2015-11-18 00:35:32 +00:00
|
|
|
|
One or several key sequence strings to be set with `spacemacs/set-leader-keys .
|
2015-02-24 04:28:23 +00:00
|
|
|
|
|
|
|
|
|
`:evil-leader-for-mode CONS CELL'
|
|
|
|
|
One or several cons cells (MODE . KEY) where MODE is a major-mode symbol
|
|
|
|
|
and KEY is a key sequence string to be set with
|
2015-11-18 00:35:32 +00:00
|
|
|
|
`spacemacs/set-leader-keys-for-major-mode'.
|
2015-02-24 04:28:23 +00:00
|
|
|
|
|
|
|
|
|
`:global-key STRING'
|
|
|
|
|
One or several key sequence strings to be set with `global-set-key'.
|
|
|
|
|
|
|
|
|
|
`:define-key CONS CELL'
|
|
|
|
|
One or several cons cells (MAP . KEY) where MAP is a mode map and KEY is a
|
|
|
|
|
key sequence string to be set with `define-key'. "
|
2018-06-07 10:13:06 +00:00
|
|
|
|
(let ((evil-leader (spacemacs/mplist-get-values props :evil-leader))
|
|
|
|
|
(evil-leader-for-mode (spacemacs/mplist-get-values props :evil-leader-for-mode))
|
|
|
|
|
(global-key (spacemacs/mplist-get-values props :global-key))
|
|
|
|
|
(def-key (spacemacs/mplist-get-values props :define-key)))
|
2016-01-19 20:59:00 +00:00
|
|
|
|
(append
|
|
|
|
|
(when evil-leader
|
|
|
|
|
`((dolist (key ',evil-leader)
|
2019-07-31 04:34:51 +00:00
|
|
|
|
(spacemacs/set-leader-keys key ',func))))
|
2016-01-19 20:59:00 +00:00
|
|
|
|
(when evil-leader-for-mode
|
|
|
|
|
`((dolist (val ',evil-leader-for-mode)
|
2019-07-31 04:34:51 +00:00
|
|
|
|
(spacemacs/set-leader-keys-for-major-mode
|
|
|
|
|
(car val) (cdr val) ',func))))
|
2016-01-19 20:59:00 +00:00
|
|
|
|
(when global-key
|
|
|
|
|
`((dolist (key ',global-key)
|
2019-07-31 04:34:51 +00:00
|
|
|
|
(global-set-key (kbd key) ',func))))
|
2016-01-19 20:59:00 +00:00
|
|
|
|
(when def-key
|
|
|
|
|
`((dolist (val ',def-key)
|
2019-07-31 04:34:51 +00:00
|
|
|
|
(define-key (eval (car val)) (kbd (cdr val)) ',func)))))))
|
2015-02-24 04:28:23 +00:00
|
|
|
|
|
2016-04-10 18:39:08 +00:00
|
|
|
|
(defun spacemacs/prettify-org-buffer ()
|
|
|
|
|
"Apply visual enchantments to the current buffer.
|
|
|
|
|
The buffer's major mode should be `org-mode'."
|
|
|
|
|
(interactive)
|
2016-06-24 08:49:48 +00:00
|
|
|
|
(unless (derived-mode-p 'org-mode)
|
|
|
|
|
(user-error "org-mode should be enabled in the current buffer."))
|
2017-06-24 01:34:59 +00:00
|
|
|
|
(if (require 'space-doc nil t)
|
|
|
|
|
(space-doc-mode)
|
|
|
|
|
;; Make ~SPC ,~ work, reference:
|
|
|
|
|
;; http://stackoverflow.com/questions/24169333/how-can-i-emphasize-or-verbatim-quote-a-comma-in-org-mode
|
|
|
|
|
(setcar (nthcdr 2 org-emphasis-regexp-components) " \t\n")
|
|
|
|
|
(org-set-emph-re 'org-emphasis-regexp-components org-emphasis-regexp-components)
|
|
|
|
|
(setq-local org-emphasis-alist '(("*" bold)
|
|
|
|
|
("/" italic)
|
|
|
|
|
("_" underline)
|
|
|
|
|
("=" org-verbatim verbatim)
|
|
|
|
|
("~" org-kbd)
|
|
|
|
|
("+"
|
|
|
|
|
(:strike-through t))))))
|
2016-04-10 18:39:08 +00:00
|
|
|
|
|
2015-06-10 15:06:30 +00:00
|
|
|
|
(defun spacemacs/view-org-file (file &optional anchor-text expand-scope)
|
2016-04-10 16:21:38 +00:00
|
|
|
|
"Open org file and apply visual enchantments.
|
2016-04-13 03:14:31 +00:00
|
|
|
|
FILE is the org file to be opened.
|
|
|
|
|
If ANCHOR-TEXT is `nil' then run `re-search-forward' with ^ (beginning-of-line).
|
|
|
|
|
If ANCHOR-TEXT is a GitHub style anchor then find a corresponding header.
|
|
|
|
|
If ANCHOR-TEXT isn't a GitHub style anchor then run `re-search-forward' with
|
|
|
|
|
ANCHOR-TEXT.
|
|
|
|
|
If EXPAND-SCOPE is `subtree' then run `outline-show-subtree' at the matched line.
|
|
|
|
|
If EXPAND-SCOPE is `all' then run `outline-show-all' at the matched line."
|
2015-04-13 06:17:48 +00:00
|
|
|
|
(interactive)
|
2015-04-15 14:30:25 +00:00
|
|
|
|
(find-file file)
|
2016-04-10 18:39:08 +00:00
|
|
|
|
(spacemacs/prettify-org-buffer)
|
|
|
|
|
(goto-char (point-min))
|
|
|
|
|
(when anchor-text
|
|
|
|
|
;; If `anchor-text' is GitHub style link.
|
|
|
|
|
(if (string-prefix-p "#" anchor-text)
|
|
|
|
|
;; If the toc-org package is loaded.
|
2017-07-02 13:48:06 +00:00
|
|
|
|
(if (configuration-layer/package-used-p 'toc-org)
|
2016-04-10 18:39:08 +00:00
|
|
|
|
;; For each heading. Search the heading that corresponds
|
|
|
|
|
;; to `anchor-text'.
|
|
|
|
|
(while (and (re-search-forward "^[\\*]+\s\\(.*\\).*$" nil t)
|
|
|
|
|
(not (string= (toc-org-hrefify-gh (match-string 1))
|
|
|
|
|
anchor-text))))
|
|
|
|
|
;; This is not a problem because without the space-doc package
|
|
|
|
|
;; those links will be opened in the browser.
|
|
|
|
|
(message (format (concat "Can't follow the GitHub style anchor: '%s' "
|
|
|
|
|
"without the org layer.") anchor-text)))
|
|
|
|
|
(re-search-forward anchor-text)))
|
|
|
|
|
(beginning-of-line)
|
|
|
|
|
(cond
|
|
|
|
|
((eq expand-scope 'subtree)
|
|
|
|
|
(outline-show-subtree))
|
|
|
|
|
((eq expand-scope 'all)
|
|
|
|
|
(outline-show-all))
|
2016-04-24 00:02:02 +00:00
|
|
|
|
(t nil)))
|
2015-04-13 06:17:48 +00:00
|
|
|
|
|
2015-06-26 16:27:40 +00:00
|
|
|
|
(defun spacemacs//test-var (pred var test-desc)
|
|
|
|
|
"Test PRED against VAR and print test result, incrementing
|
|
|
|
|
passed-tests and total-tests."
|
|
|
|
|
(let ((var-name (symbol-name var))
|
|
|
|
|
(var-val (symbol-value var)))
|
|
|
|
|
(when (boundp 'total-tests) (setq total-tests (1+ total-tests)))
|
2015-06-30 02:53:51 +00:00
|
|
|
|
(insert (format "** TEST: [[file:%s::%s][%s]] %s\n"
|
|
|
|
|
dotspacemacs-filepath var-name var-name test-desc))
|
2015-06-26 16:27:40 +00:00
|
|
|
|
(if (funcall pred var-val)
|
|
|
|
|
(progn
|
|
|
|
|
(when (boundp 'passed-tests) (setq passed-tests (1+ passed-tests)))
|
2015-06-30 02:53:51 +00:00
|
|
|
|
(insert (format "*** PASS: %s\n" var-val)))
|
|
|
|
|
(insert (propertize (format "*** FAIL: %s\n" var-val)
|
2019-07-31 04:34:51 +00:00
|
|
|
|
'font-lock-face 'font-lock-warning-face)))))
|
2015-06-26 16:27:40 +00:00
|
|
|
|
|
|
|
|
|
(defun spacemacs//test-list (pred varlist test-desc &optional element-desc)
|
|
|
|
|
"Test PRED against each element of VARLIST and print test
|
|
|
|
|
result, incrementing passed-tests and total-tests."
|
|
|
|
|
(let ((varlist-name (symbol-name varlist))
|
|
|
|
|
(varlist-val (symbol-value varlist)))
|
|
|
|
|
(if element-desc
|
2015-06-30 02:53:51 +00:00
|
|
|
|
(insert (format "** TEST: Each %s in [[file:%s::%s][%s]] %s\n"
|
|
|
|
|
element-desc dotspacemacs-filepath varlist-name
|
|
|
|
|
varlist-name test-desc))
|
|
|
|
|
(insert (format "** TEST: Each element of [[file:%s::%s][%s]] %s\n"
|
|
|
|
|
dotspacemacs-filepath varlist-name varlist-name
|
|
|
|
|
test-desc)))
|
2015-06-26 16:27:40 +00:00
|
|
|
|
(dolist (var varlist-val)
|
|
|
|
|
(when (boundp 'total-tests) (setq total-tests (1+ total-tests)))
|
|
|
|
|
(if (funcall pred var)
|
|
|
|
|
(progn
|
|
|
|
|
(when (boundp 'passed-tests) (setq passed-tests (1+ passed-tests)))
|
2015-06-30 02:53:51 +00:00
|
|
|
|
(insert (format "*** PASS: %s\n" var)))
|
|
|
|
|
(insert (propertize (format "*** FAIL: %s\n" var) 'font-lock-face 'font-lock-warning-face))))))
|
2015-06-26 16:27:40 +00:00
|
|
|
|
|
2015-12-11 08:07:15 +00:00
|
|
|
|
;; hide mode line
|
|
|
|
|
;; from http://bzg.fr/emacs-hide-mode-line.html
|
|
|
|
|
(defvar-local hidden-mode-line-mode nil)
|
2015-12-16 15:10:26 +00:00
|
|
|
|
(defvar-local hide-mode-line nil)
|
2015-12-11 08:07:15 +00:00
|
|
|
|
(define-minor-mode hidden-mode-line-mode
|
|
|
|
|
"Minor mode to hide the mode-line in the current buffer."
|
|
|
|
|
:init-value nil
|
|
|
|
|
:global t
|
|
|
|
|
:variable hidden-mode-line-mode
|
|
|
|
|
:group 'editing-basics
|
|
|
|
|
(if hidden-mode-line-mode
|
|
|
|
|
(setq hide-mode-line mode-line-format
|
|
|
|
|
mode-line-format nil)
|
|
|
|
|
(setq mode-line-format hide-mode-line
|
|
|
|
|
hide-mode-line nil))
|
|
|
|
|
(force-mode-line-update)
|
|
|
|
|
;; Apparently force-mode-line-update is not always enough to
|
|
|
|
|
;; redisplay the mode-line
|
|
|
|
|
(redraw-display)
|
|
|
|
|
(when (and (called-interactively-p 'interactive)
|
|
|
|
|
hidden-mode-line-mode)
|
|
|
|
|
(run-with-idle-timer
|
|
|
|
|
0 nil 'message
|
|
|
|
|
(concat "Hidden Mode Line Mode enabled. "
|
|
|
|
|
"Use M-x hidden-mode-line-mode to make the mode-line appear."))))
|
|
|
|
|
|
2018-12-03 21:29:38 +00:00
|
|
|
|
;; https://github.com/syl20bnr/spacemacs/issues/8414
|
2019-11-24 01:07:15 +00:00
|
|
|
|
(defun spacemacs/recompile-elpa (arg &optional dir)
|
|
|
|
|
"Compile or recompile packages in elpa or given directory.
|
|
|
|
|
This function compiles all `.el' files in the elpa directory
|
|
|
|
|
if it's corresponding `.elc' file is missing or outdated.
|
2018-12-03 21:29:38 +00:00
|
|
|
|
|
2019-11-24 01:07:15 +00:00
|
|
|
|
This is useful if you switch Emacs versions or there
|
|
|
|
|
are issues with a local package which require a recompile.
|
2018-12-03 21:29:38 +00:00
|
|
|
|
|
2019-11-24 01:07:15 +00:00
|
|
|
|
If ARG is non-nil, force recompile of all found `.el' files.
|
|
|
|
|
If DIR is non-nil, use a given directory for recompilation instead of elpa."
|
2018-12-03 21:29:38 +00:00
|
|
|
|
(interactive "P")
|
2019-11-24 01:07:15 +00:00
|
|
|
|
;; Replace default directories if dir parameter is filled
|
|
|
|
|
(let ((user-emacs-dir (or dir user-emacs-directory))
|
|
|
|
|
(package-user-dir (or dir package-user-dir)))
|
|
|
|
|
;; First argument must be 0 (not nil) to get missing .elc files rebuilt.
|
|
|
|
|
;; Bonus: Optionally force recompilation with universal ARG
|
|
|
|
|
(when arg
|
|
|
|
|
(seq-do
|
|
|
|
|
(lambda (fname)
|
|
|
|
|
(when (file-exists-p fname)
|
|
|
|
|
(delete-file fname)))
|
|
|
|
|
(directory-files-recursively user-emacs-directory "\\.elc$" t)))
|
|
|
|
|
(byte-recompile-directory package-user-dir 0 arg)))
|
2019-11-06 19:15:00 +00:00
|
|
|
|
|
2016-01-22 15:21:15 +00:00
|
|
|
|
(defun spacemacs/register-repl (feature repl-func &optional tag)
|
2016-01-13 20:47:07 +00:00
|
|
|
|
"Register REPL-FUNC to the global list of REPLs SPACEMACS-REPL-LIST.
|
2016-01-22 15:21:15 +00:00
|
|
|
|
FEATURE will be loaded before running the REPL, in case it is not already
|
|
|
|
|
loaded. If TAG is non-nil, it will be used as the string to show in the helm
|
|
|
|
|
buffer."
|
|
|
|
|
(push `(,(or tag (symbol-name repl-func))
|
|
|
|
|
. (,feature . ,repl-func))
|
|
|
|
|
spacemacs-repl-list))
|
2016-01-13 20:47:07 +00:00
|
|
|
|
|
2016-10-09 16:57:46 +00:00
|
|
|
|
;; http://stackoverflow.com/questions/11847547/emacs-regexp-count-occurrences
|
|
|
|
|
(defun spacemacs/how-many-str (regexp str)
|
2018-01-07 02:38:13 +00:00
|
|
|
|
(cl-loop with start = 0
|
2019-07-31 04:34:51 +00:00
|
|
|
|
for count from 0
|
|
|
|
|
while (string-match regexp str start)
|
|
|
|
|
do (setq start (match-end 0))
|
|
|
|
|
finally return count))
|
2016-10-09 16:57:46 +00:00
|
|
|
|
|
|
|
|
|
(defun spacemacs/echo (msg &rest args)
|
|
|
|
|
"Display MSG in echo-area without logging it in *Messages* buffer."
|
|
|
|
|
(interactive)
|
|
|
|
|
(let ((message-log-max nil))
|
|
|
|
|
(apply 'message msg args)))
|
|
|
|
|
|
2017-03-09 14:30:44 +00:00
|
|
|
|
(defun spacemacs/derived-mode-p (mode &rest modes)
|
|
|
|
|
"Non-nil if MODE is derived from one of MODES."
|
|
|
|
|
;; We could have copied the built-in `derived-mode-p' and modified it a bit so
|
|
|
|
|
;; it works on arbitrary modes instead of only the current major-mode. We
|
|
|
|
|
;; don't do that because then we will need to modify the function if
|
|
|
|
|
;; `derived-mode-p' changes.
|
|
|
|
|
(let ((major-mode mode))
|
|
|
|
|
(apply #'derived-mode-p modes)))
|
|
|
|
|
|
2016-10-09 16:57:46 +00:00
|
|
|
|
(defun spacemacs/alternate-buffer (&optional window)
|
|
|
|
|
"Switch back and forth between current and last buffer in the
|
2019-07-31 04:34:51 +00:00
|
|
|
|
current window.
|
|
|
|
|
|
|
|
|
|
If `spacemacs-layouts-restrict-spc-tab' is `t' then this only switches between
|
|
|
|
|
the current layouts buffers."
|
2016-10-09 16:57:46 +00:00
|
|
|
|
(interactive)
|
2020-01-07 11:03:54 +00:00
|
|
|
|
(cl-destructuring-bind (buf start pos)
|
2019-12-08 08:03:03 +00:00
|
|
|
|
(if (bound-and-true-p spacemacs-layouts-restrict-spc-tab)
|
2019-07-31 04:34:51 +00:00
|
|
|
|
(let ((buffer-list (persp-buffer-list))
|
|
|
|
|
(my-buffer (window-buffer window)))
|
|
|
|
|
;; find buffer of the same persp in window
|
|
|
|
|
(seq-find (lambda (it) ;; predicate
|
|
|
|
|
(and (not (eq (car it) my-buffer))
|
|
|
|
|
(member (car it) buffer-list)))
|
|
|
|
|
(window-prev-buffers)
|
|
|
|
|
;; default if found none
|
|
|
|
|
(list nil nil nil)))
|
|
|
|
|
(or (cl-find (window-buffer window) (window-prev-buffers)
|
|
|
|
|
:key #'car :test-not #'eq)
|
|
|
|
|
(list (other-buffer) nil nil)))
|
|
|
|
|
(if (not buf)
|
|
|
|
|
(message "Last buffer not found.")
|
|
|
|
|
(set-window-buffer-start-and-point window buf start pos))))
|
2016-10-09 16:57:46 +00:00
|
|
|
|
|
2016-12-25 06:15:35 +00:00
|
|
|
|
(defun spacemacs/alternate-window ()
|
|
|
|
|
"Switch back and forth between current and last window in the
|
|
|
|
|
current frame."
|
|
|
|
|
(interactive)
|
|
|
|
|
(let (;; switch to first window previously shown in this frame
|
|
|
|
|
(prev-window (get-mru-window nil t t)))
|
|
|
|
|
;; Check window was not found successfully
|
|
|
|
|
(unless prev-window (user-error "Last window not found."))
|
|
|
|
|
(select-window prev-window)))
|
|
|
|
|
|
2016-10-09 16:57:46 +00:00
|
|
|
|
(defun spacemacs/comint-clear-buffer ()
|
|
|
|
|
(interactive)
|
|
|
|
|
(let ((comint-buffer-maximum-size 0))
|
|
|
|
|
(comint-truncate-buffer)))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;; Generalized next-error system ("gne")
|
|
|
|
|
|
|
|
|
|
(defun spacemacs/error-delegate ()
|
|
|
|
|
"Decide which error API to delegate to.
|
|
|
|
|
|
|
|
|
|
Delegates to flycheck if it is enabled and the next-error buffer
|
|
|
|
|
is not visible. Otherwise delegates to regular Emacs next-error."
|
|
|
|
|
(if (and (bound-and-true-p flycheck-mode)
|
2019-04-21 03:58:21 +00:00
|
|
|
|
(not next-error-function))
|
2016-10-09 16:57:46 +00:00
|
|
|
|
'flycheck
|
|
|
|
|
'emacs))
|
|
|
|
|
|
|
|
|
|
(defun spacemacs/next-error (&optional n reset)
|
|
|
|
|
"Dispatch to flycheck or standard emacs error."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(let ((sys (spacemacs/error-delegate)))
|
|
|
|
|
(cond
|
|
|
|
|
((eq 'flycheck sys) (call-interactively 'flycheck-next-error))
|
|
|
|
|
((eq 'emacs sys) (call-interactively 'next-error)))))
|
|
|
|
|
|
2018-05-07 10:06:27 +00:00
|
|
|
|
(defun spacemacs/last-error ()
|
|
|
|
|
"Go to last flycheck or standard emacs error."
|
|
|
|
|
(interactive)
|
2019-11-03 19:35:49 +00:00
|
|
|
|
(when (save-excursion (spacemacs/next-error))
|
|
|
|
|
(evil-goto-line)
|
|
|
|
|
(spacemacs/previous-error)))
|
2018-05-07 10:06:27 +00:00
|
|
|
|
|
2016-10-09 16:57:46 +00:00
|
|
|
|
(defun spacemacs/previous-error (&optional n reset)
|
|
|
|
|
"Dispatch to flycheck or standard emacs error."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(let ((sys (spacemacs/error-delegate)))
|
|
|
|
|
(cond
|
|
|
|
|
((eq 'flycheck sys) (call-interactively 'flycheck-previous-error))
|
|
|
|
|
((eq 'emacs sys) (call-interactively 'previous-error)))))
|
|
|
|
|
|
|
|
|
|
(defvar-local spacemacs--gne-min-line nil
|
|
|
|
|
"The first line in the buffer that is a valid result.")
|
|
|
|
|
(defvar-local spacemacs--gne-max-line nil
|
|
|
|
|
"The last line in the buffer that is a valid result.")
|
|
|
|
|
(defvar-local spacemacs--gne-cur-line 0
|
|
|
|
|
"The current line in the buffer. (It is problematic to use
|
|
|
|
|
point for this.)")
|
|
|
|
|
(defvar-local spacemacs--gne-line-func nil
|
|
|
|
|
"The function to call to visit the result on a line.")
|
|
|
|
|
|
|
|
|
|
(defun spacemacs/gne-next (num reset)
|
|
|
|
|
"A generalized next-error function. This function can be used
|
|
|
|
|
as `next-error-function' in any buffer that conforms to the
|
|
|
|
|
Spacemacs generalized next-error API.
|
|
|
|
|
|
|
|
|
|
The variables `spacemacs--gne-min-line',
|
|
|
|
|
`spacemacs--gne-max-line', and `spacemacs--line-func' must be
|
|
|
|
|
set."
|
|
|
|
|
(when reset (setq spacemacs--gne-cur-line
|
|
|
|
|
spacemacs--gne-min-line))
|
|
|
|
|
(setq spacemacs--gne-cur-line
|
|
|
|
|
(min spacemacs--gne-max-line
|
|
|
|
|
(max spacemacs--gne-min-line
|
|
|
|
|
(+ num spacemacs--gne-cur-line))))
|
2020-10-05 00:07:12 +00:00
|
|
|
|
(goto-char (point-min))
|
|
|
|
|
(forward-line (1- spacemacs--gne-cur-line))
|
2016-10-09 16:57:46 +00:00
|
|
|
|
(funcall spacemacs--gne-line-func
|
|
|
|
|
(buffer-substring (point-at-bol) (point-at-eol))))
|
|
|
|
|
|
2020-06-03 22:14:51 +00:00
|
|
|
|
(defun spacemacs/terminal-fix-mode-line-indicator-overlap (str)
|
|
|
|
|
"Add a space between two mode line indicators,
|
|
|
|
|
to fix an overlapping issue, that occurs when
|
|
|
|
|
Spacemacs is started in a terminal,
|
|
|
|
|
and a modes mode line name is diminished to:
|
|
|
|
|
- A unicode character followed by a non unicode character, ex: \" Ⓔh\"
|
|
|
|
|
- Or to two unicode characters, ex: \" Ⓔⓗ\""
|
|
|
|
|
(let ((first-char (substring str 1 2)) ; first char after the space
|
|
|
|
|
second-char)
|
|
|
|
|
(if (equal (char-charset (string-to-char first-char)) 'unicode)
|
|
|
|
|
(progn
|
|
|
|
|
(setq second-char (substring str 2 3)) ; second char after the space
|
|
|
|
|
(concat first-char " " second-char))
|
|
|
|
|
str)))
|
|
|
|
|
|
2015-01-27 03:51:47 +00:00
|
|
|
|
(provide 'core-funcs)
|