Update vim-empty-lines.
Patched file should fix some bugs.
This commit is contained in:
parent
7ccf15c526
commit
24e2c0dcab
3 changed files with 328 additions and 14 deletions
39
contrib/vim-empty-lines/extensions.el
Normal file
39
contrib/vim-empty-lines/extensions.el
Normal file
|
@ -0,0 +1,39 @@
|
|||
;;; extensions.el --- vim-empty-lines Layer extensions File for Spacemacs
|
||||
;;
|
||||
;; Copyright (c) 2012-2014 Sylvain Benner
|
||||
;; Copyright (c) 2014-2015 Sylvain Benner & Contributors
|
||||
;;
|
||||
;; Author: Sylvain Benner <sylvain.benner@gmail.com>
|
||||
;; URL: https://github.com/syl20bnr/spacemacs
|
||||
;;
|
||||
;; This file is not part of GNU Emacs.
|
||||
;;
|
||||
;;; License: GPLv3
|
||||
|
||||
(setq vim-empty-lines-pre-extensions '())
|
||||
|
||||
(setq vim-empty-lines-post-extensions '(vim-empty-lines-mode))
|
||||
|
||||
|
||||
(defun vim-empty-lines/init-vim-empty-lines-mode ()
|
||||
(use-package vim-empty-lines-mode
|
||||
:diminish vim-empty-lines-mode
|
||||
:config
|
||||
(progn
|
||||
(global-vim-empty-lines-mode)
|
||||
(spacemacs|add-toggle vim-empty-lines-mode
|
||||
:status vim-empty-lines-mode
|
||||
:on (global-vim-empty-lines-mode)
|
||||
:off (global-vim-empty-lines-mode -1)
|
||||
:documentation
|
||||
(concat "Display an overlay of ~ on "
|
||||
"empty lines.")
|
||||
:evil-leader "t~")
|
||||
;; don't enable it on spacemacs home buffer
|
||||
(with-current-buffer "*spacemacs*"
|
||||
(vim-empty-lines-mode -1))
|
||||
;; after a major mode is loaded, check if the buffer is read only
|
||||
;; if so, disable vim-empty-lines-mode
|
||||
(add-hook 'after-change-major-mode-hook (lambda ()
|
||||
(when buffer-read-only
|
||||
(vim-empty-lines-mode -1)))))))
|
|
@ -0,0 +1,287 @@
|
|||
;;; vim-empty-lines-mode.el --- Vim-like empty line indicator at end of files.
|
||||
|
||||
;; Copyright (C) 2015 Jonne Mickelin
|
||||
|
||||
;; Author: Jonne Mickelin <jonne@ljhms.com>
|
||||
;; Created: 06 Jan 2015
|
||||
;; Version: 0.1
|
||||
;; Keywords: emulations
|
||||
;; URL: https://github.com/jmickelin/vim-empty-lines-mode
|
||||
;; Package-Requires: ((emacs "23"))
|
||||
|
||||
;; This file is not part of GNU Emacs.
|
||||
|
||||
;; 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/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; This mode emulates the way that vim indicates the end of a file,
|
||||
;; that is by putting a "tilde" character (~) on any empty line that
|
||||
;; follows the end of file.
|
||||
|
||||
;; Emacs provides a similar functionality that inserts a bitmap in the
|
||||
;; fringe on the extraneous lines. By customizing
|
||||
;; `indicate-empty-lines' and `fringe-indicator-alist' it is possible
|
||||
;; to nearly emulate the vim behaviour.
|
||||
|
||||
;; However, there is a slight difference in what the two editors
|
||||
;; consider to be "empty lines".
|
||||
|
||||
;; A line in vim can be considered to contain the newline character
|
||||
;; that ended the previous line, as well as the other visible
|
||||
;; characters. Equivalently, a line is empty only if it contains no
|
||||
;; text and the previous line has no trailing whitespace.
|
||||
|
||||
;; Example:
|
||||
|
||||
;; foo <- not empty
|
||||
;; \nbar <- not empty
|
||||
;; \n <- not empty
|
||||
;; ~ <- empty
|
||||
;; ~ <- empty
|
||||
;;
|
||||
;; foo <- not empty
|
||||
;; \nbar <- not empty
|
||||
;; ~ <- empty
|
||||
;; ~ <- empty
|
||||
|
||||
;; A line in emacs, on the other hand, will contain the newline
|
||||
;; character that breaks it. Thus a line is empty even if the previous
|
||||
;; line has a trailing linebreak.
|
||||
|
||||
;; Example:
|
||||
|
||||
;; foo\n <- not empty
|
||||
;; bar\n <- not empty
|
||||
;; ~ <- empty
|
||||
;; ~ <- empty
|
||||
;; ;
|
||||
;; foo\n <- not empty
|
||||
;; bar <- not empty
|
||||
;; ~ <- empty
|
||||
;; ~ <- empty
|
||||
|
||||
;; Note that Emacs displays the two cases identically!
|
||||
|
||||
;; There is currently (as of Emacs 24.4) no way to implement the
|
||||
;; vim-like behaviour for `indicate-empty-lines' short of modifying
|
||||
;; the Emacs core.
|
||||
|
||||
;; This module emulates the vim-like behaviour using a different
|
||||
;; approach, namely by inserting at the end of the buffer a read-only
|
||||
;; overlay containing the indicators for the empty lines. This has the
|
||||
;; added advantage that it's trivial to customize the indicator to an
|
||||
;; arbitrary string, and customize its text properties.
|
||||
|
||||
;; To enable `vim-empty-lines-mode' in a buffer, run
|
||||
;; (vim-empty-lines-mode)
|
||||
|
||||
;; To enable it globally, run
|
||||
;; (global-vim-empty-lines-mode)
|
||||
|
||||
;; The string that indicates an empty line can be customized, e.g.
|
||||
;; (setq vim-empty-lines-indicator "**********************")
|
||||
|
||||
;; The face that is used to display the indicators is `vim-empty-lines-face'.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(defgroup vim-empty-lines-mode
|
||||
nil
|
||||
"Vim-like empty line indicators."
|
||||
:group 'emulations
|
||||
:prefix "vim-empty-lines")
|
||||
|
||||
(defface vim-empty-lines-face
|
||||
'((t (:inherit font-lock-comment-face)))
|
||||
"Face for empty lines in `vim-empty-lines-mode'."
|
||||
:group 'vim-empty-lines-mode)
|
||||
|
||||
(defcustom vim-empty-lines-indicator "~"
|
||||
"String to display on lines following end-of-buffer in `vim-empty-lines-mode'.
|
||||
|
||||
Must not contain '\\n'."
|
||||
:group 'vim-empty-lines-mode)
|
||||
|
||||
(defvar vim-empty-lines-overlay nil
|
||||
"Overlay that displays the empty line indicators.")
|
||||
(put 'vim-empty-lines-overlay 'permanent-local t)
|
||||
|
||||
(defun vim-empty-lines-create-overlay ()
|
||||
(setq-local vim-empty-lines-overlay (make-overlay (point-max)
|
||||
(point-max)
|
||||
nil
|
||||
t t))
|
||||
(overlay-put vim-empty-lines-overlay 'window t))
|
||||
|
||||
(defun vim-empty-lines-count-screen-lines (beg end &optional max)
|
||||
"Return the number of screen lines in the region.
|
||||
|
||||
Taken from `count-screen-lines' and quite stripped down.
|
||||
Unlike `count-screen-lines', calls `vertical-motion' with MAX as the
|
||||
argument for efficiencies. It is too expensive calling `vertical-motion'
|
||||
with `buffer-size' if the buffer is large."
|
||||
(let (count-final-newline
|
||||
window)
|
||||
(if (= beg end)
|
||||
0
|
||||
(save-excursion
|
||||
(save-restriction
|
||||
(widen)
|
||||
(narrow-to-region (min beg end)
|
||||
(if (and (not count-final-newline)
|
||||
(= ?\n (char-before (max beg end))))
|
||||
(1- (max beg end))
|
||||
(max beg end)))
|
||||
(goto-char (point-min))
|
||||
(1+ (vertical-motion (or max (buffer-size)) ; XXX: changed
|
||||
window)))))))
|
||||
|
||||
(defun vim-empty-lines-nlines-after-buffer-end (window &optional window-start)
|
||||
(with-current-buffer (window-buffer window)
|
||||
(if (and window-start ;; chance to optimize for some cases.
|
||||
(or (and (window-end) (= (point-max) (window-end)))
|
||||
(not (pos-visible-in-window-p (point-max) window))))
|
||||
0
|
||||
(vim-empty-lines-nlines-after-buffer-end-aux window))))
|
||||
|
||||
(defun vim-empty-lines-nlines-after-buffer-end-aux (window)
|
||||
(save-selected-window
|
||||
(with-selected-window window
|
||||
(with-current-buffer (window-buffer)
|
||||
(let ((screen-height (- (window-height)
|
||||
1 ;; mode-line
|
||||
(if header-line-format 1 0))))
|
||||
(- screen-height
|
||||
(1- (vim-empty-lines-count-screen-lines
|
||||
(window-start) (point-max) screen-height))))))))
|
||||
|
||||
(defun vim-empty-lines-update-overlay (&optional window window-start)
|
||||
(let ((w (or window
|
||||
(let ((w (selected-window)))
|
||||
(and (window-valid-p w) w)))))
|
||||
;; `w' could be nil but it's ok for `window-height', `window-start' etc.
|
||||
(when (overlayp vim-empty-lines-overlay)
|
||||
(vim-empty-lines-update-overlay-aux
|
||||
(apply 'max
|
||||
(vim-empty-lines-nlines-after-buffer-end w window-start)
|
||||
(mapcar 'vim-empty-lines-nlines-after-buffer-end
|
||||
(remq w (get-buffer-window-list nil nil t)))))
|
||||
(move-overlay vim-empty-lines-overlay (point-max) (point-max)))))
|
||||
|
||||
(defun vim-empty-lines-update-overlay-aux (nlines-after-buffer-end)
|
||||
(when (> nlines-after-buffer-end 1)
|
||||
(save-excursion
|
||||
(let ((indicators
|
||||
(apply 'concat
|
||||
(make-list nlines-after-buffer-end
|
||||
(concat "\n" vim-empty-lines-indicator)))))
|
||||
(overlay-put vim-empty-lines-overlay
|
||||
'after-string
|
||||
(concat (propertize " "
|
||||
;; Forbid movement past
|
||||
;; the beginning of the
|
||||
;; after-string.
|
||||
'cursor nlines-after-buffer-end)
|
||||
(propertize indicators
|
||||
'face 'vim-empty-lines-face)))))))
|
||||
|
||||
(defun vim-empty-lines-update-overlay-windows ()
|
||||
(with-selected-frame (selected-frame)
|
||||
(save-selected-window
|
||||
(mapc (lambda (w)
|
||||
(with-selected-window w
|
||||
(vim-empty-lines-update-overlay w)))
|
||||
(window-list (selected-frame) -1)))))
|
||||
|
||||
(defun vim-empty-lines-hide-overlay ()
|
||||
(when (overlayp vim-empty-lines-overlay)
|
||||
(let ((ov vim-empty-lines-overlay))
|
||||
(overlay-put ov 'invisible nil)
|
||||
(overlay-put ov 'display nil)
|
||||
(overlay-put ov 'after-string nil))))
|
||||
|
||||
(defvar vim-empty-lines-initialize-p nil)
|
||||
|
||||
(defun vim-empty-lines-initialize-maybe ()
|
||||
"Setup some advices to emacs primitives for workarounds"
|
||||
(unless vim-empty-lines-initialize-p
|
||||
(setq vim-empty-lines-initialize-p t)
|
||||
|
||||
;; A kludge to bug#19553
|
||||
;; fixed in b544ab561fcb575790c963a2eda51524fa366409
|
||||
;; XXX: The fix is in the emacs-24 branch only at this time.
|
||||
(unless (and (version< emacs-version "25")
|
||||
(version< "24.4.51" emacs-version))
|
||||
(eval-when-compile
|
||||
(defmacro vim-empty-lines-advice-add-overlay-handling (&rest functions)
|
||||
`(progn
|
||||
,@(mapcar
|
||||
(lambda (function)
|
||||
`(defadvice ,function (around vim-empty-lines activate)
|
||||
(if (not (overlayp vim-empty-lines-overlay))
|
||||
ad-do-it
|
||||
(let ((inhibit-redisplay t) ;;Hope not to break anything
|
||||
(p (overlay-start vim-empty-lines-overlay)))
|
||||
(delete-overlay vim-empty-lines-overlay)
|
||||
(unwind-protect ad-do-it
|
||||
(move-overlay vim-empty-lines-overlay p p))))))
|
||||
functions))))
|
||||
|
||||
(vim-empty-lines-advice-add-overlay-handling vertical-motion
|
||||
move-to-window-line))))
|
||||
|
||||
;;;###autoload
|
||||
(define-minor-mode vim-empty-lines-mode
|
||||
"Display `vim-empty-lines-indicator' on visible lines after the end of the buffer.
|
||||
|
||||
This differs from `indicate-empty-lines' in the way that it deals
|
||||
with trailing newlines."
|
||||
:lighter " ~"
|
||||
:global nil
|
||||
(if vim-empty-lines-mode
|
||||
(progn
|
||||
(unless (overlayp vim-empty-lines-overlay)
|
||||
(vim-empty-lines-create-overlay))
|
||||
(vim-empty-lines-initialize-maybe)
|
||||
(make-local-variable 'vim-empty-lines-overlay)
|
||||
(vim-empty-lines-create-overlay)
|
||||
(vim-empty-lines-update-overlay)
|
||||
(add-hook 'post-command-hook 'vim-empty-lines-update-overlay t)
|
||||
(add-hook 'window-scroll-functions 'vim-empty-lines-update-overlay t)
|
||||
(add-hook 'window-configuration-change-hook
|
||||
'vim-empty-lines-update-overlay-windows t))
|
||||
(remove-hook 'post-command-hook 'vim-empty-lines-update-overlay t)
|
||||
(remove-hook 'window-scroll-functions 'vim-empty-lines-update-overlay t)
|
||||
(remove-hook 'window-configuration-change-hook
|
||||
'vim-empty-lines-update-overlay-windows t)
|
||||
(when (overlayp vim-empty-lines-overlay)
|
||||
(delete-overlay vim-empty-lines-overlay)
|
||||
(setq vim-empty-lines-overlay nil))))
|
||||
|
||||
;;;###autoload
|
||||
(define-global-minor-mode global-vim-empty-lines-mode
|
||||
vim-empty-lines-mode
|
||||
(lambda ()
|
||||
(unless (or (minibufferp)
|
||||
;; Is there really no built-in function for detecting
|
||||
;; the echo area?
|
||||
(string-match-p "\\*Echo Area [0-9]+\\*" (buffer-name)))
|
||||
(vim-empty-lines-mode +1)))
|
||||
:group 'vim-empty-lines-mode
|
||||
:require 'vim-empty-lines-mode)
|
||||
|
||||
(provide 'vim-empty-lines-mode)
|
||||
|
||||
;;; vim-empty-lines-mode.el ends here
|
|
@ -1,16 +1,4 @@
|
|||
(setq vim-empty-lines-packages
|
||||
'(vim-empty-lines-mode))
|
||||
(setq vim-empty-lines-packages '())
|
||||
|
||||
(setq vim-empty-lines-excluded-packages
|
||||
'(vi-tilde-fringe))
|
||||
|
||||
(defun vim-empty-lines/init-vim-empty-lines-mode ()
|
||||
(use-package vim-empty-lines-mode
|
||||
:defer t
|
||||
:init
|
||||
(add-to-hooks 'vim-empty-lines-mode '(prog-mode-hook
|
||||
erlang-mode-hook
|
||||
text-mode-hook
|
||||
ess-mode-hook))
|
||||
:config
|
||||
(spacemacs|hide-lighter vim-empty-lines-mode)))
|
||||
'(vi-tilde-fringe))
|
||||
|
|
Reference in a new issue