branch: master commit 1d4618b022bb1cea6781f50f5009e68b7689a1cd Author: João Távora <joaotav...@gmail.com> Commit: João Távora <joaotav...@gmail.com>
Closes #504: Correctly discover buffers needing snippets immediately * yasnippet-tests.el (issue-504-tricky-jit): New test. * yasnippet.el (yas-load-directory): Use a new `impatient-buffers' local and call `yas--load-pending-juts' in all those at the end. * yasnippet.el (cl-lib): Don't need `eval-and-compile'. --- yasnippet-tests.el | 17 ++++++++++++ yasnippet.el | 71 ++++++++++++++++++++++++++++----------------------- 2 files changed, 56 insertions(+), 32 deletions(-) diff --git a/yasnippet-tests.el b/yasnippet-tests.el index 4b3a440..7653d31 100644 --- a/yasnippet-tests.el +++ b/yasnippet-tests.el @@ -485,6 +485,23 @@ TODO: correct this bug!" (should (= (length expected) (length observed))))))) +(ert-deftest issue-504-tricky-jit () + (define-derived-mode yas--test-mode c-mode "Just a test mode") + (define-derived-mode yas--another-test-mode c-mode "Another test mode") + (yas-with-snippet-dirs + '((".emacs.d/snippets" + ("yas--another-test-mode" + (".yas-parents" . "yas--test-mode")) + ("yas--test-mode"))) + (let ((b (with-current-buffer (generate-new-buffer "*yas-test*") + (yas--another-test-mode) + (current-buffer)))) + (unwind-protect + (progn + (yas-reload-all) + (should (= 0 (hash-table-count yas--scheduled-jit-loads)))) + (kill-buffer b))))) + (defun yas--basic-jit-loading-1 () (with-temp-buffer (should (= 4 (hash-table-count yas--scheduled-jit-loads))) diff --git a/yasnippet.el b/yasnippet.el index 821e748..adcd44d 100644 --- a/yasnippet.el +++ b/yasnippet.el @@ -130,8 +130,7 @@ ;;; Code: (require 'cl) -(eval-and-compile - (require 'cl-lib)) +(require 'cl-lib) (require 'easymenu) (require 'help-mode) @@ -1736,36 +1735,44 @@ With prefix argument USE-JIT do jit-loading of snippets." current-prefix-arg t)) (unless yas-snippet-dirs (setq yas-snippet-dirs top-level-dir)) - (dolist (dir (yas--subdirs top-level-dir)) - (let* ((major-mode-and-parents (yas--compute-major-mode-and-parents - (concat dir "/dummy"))) - (mode-sym (car major-mode-and-parents)) - (parents (cdr major-mode-and-parents))) - ;; Attention: The parents and the menus are already defined - ;; here, even if the snippets are later jit-loaded. - ;; - ;; * We need to know the parents at this point since entering a - ;; given mode should jit load for its parents - ;; immediately. This could be reviewed, the parents could be - ;; discovered just-in-time-as well - ;; - ;; * We need to create the menus here to support the `full' - ;; option to `yas-use-menu' (all known snippet menus are shown to the user) - ;; - (yas--define-parents mode-sym parents) - (yas--menu-keymap-get-create mode-sym) - (let ((fun `(lambda () ;; FIXME: Simulating lexical-binding. - (yas--load-directory-1 ',dir ',mode-sym)))) - (if (and use-jit - (not (some #'(lambda (buffer) - (with-current-buffer buffer - ;; FIXME: Shouldn't this use derived-mode-p? - (when (eq major-mode mode-sym) - (yas--message 3 "Discovered there was already %s in %s" buffer mode-sym) - t))) - (buffer-list)))) - (yas--schedule-jit mode-sym fun) - (funcall fun))))) + (let ((impatient-buffers)) + (dolist (dir (yas--subdirs top-level-dir)) + (let* ((major-mode-and-parents (yas--compute-major-mode-and-parents + (concat dir "/dummy"))) + (mode-sym (car major-mode-and-parents)) + (parents (cdr major-mode-and-parents))) + ;; Attention: The parents and the menus are already defined + ;; here, even if the snippets are later jit-loaded. + ;; + ;; * We need to know the parents at this point since entering a + ;; given mode should jit load for its parents + ;; immediately. This could be reviewed, the parents could be + ;; discovered just-in-time-as well + ;; + ;; * We need to create the menus here to support the `full' + ;; option to `yas-use-menu' (all known snippet menus are shown to the user) + ;; + (yas--define-parents mode-sym parents) + (yas--menu-keymap-get-create mode-sym) + (let ((fun `(lambda () ;; FIXME: Simulating lexical-binding. + (yas--load-directory-1 ',dir ',mode-sym)))) + (if use-jit + (yas--schedule-jit mode-sym fun) + (funcall fun))) + ;; Look for buffers that are already in `mode-sym', and so + ;; need the new snippets immediately... + ;; + (when use-jit + (cl-loop for buffer in (buffer-list) + do (with-current-buffer buffer + (when (eq major-mode mode-sym) + (yas--message 3 "Discovered there was already %s in %s" buffer mode-sym) + (push buffer impatient-buffers))))))) + ;; ...after TOP-LEVEL-DIR has been completely loaded, call + ;; `yas--load-pending-jits' in these impatient buffers. + ;; + (cl-loop for buffer in impatient-buffers + do (with-current-buffer buffer (yas--load-pending-jits)))) (when interactive (yas--message 3 "Loaded snippets from %s." top-level-dir)))