/vendor/yasnippet/yasnippet.el
Emacs Lisp | 3676 lines | 2704 code | 437 blank | 535 comment | 79 complexity | b772cd5ccc2eb9cb7294e279dfa92b89 MD5 | raw file
Possible License(s): GPL-2.0
Large files files are truncated, but you can click here to view the full file
1;;; Yasnippet.el --- Yet another snippet extension for Emacs. 2 3;; Copyright 2008 pluskid 4;; 2009 pluskid, joaotavora 5 6;; Authors: pluskid <pluskid@gmail.com>, joaotavora <joaotavora@gmail.com> 7;; Version: 0.6.1 8;; Package-version: 0.6.1c 9;; X-URL: http://code.google.com/p/yasnippet/ 10;; Keywords: convenience, emulation 11;; URL: http://code.google.com/p/yasnippet/ 12;; EmacsWiki: YaSnippetMode 13 14;; This file is free software; you can redistribute it and/or modify 15;; it under the terms of the GNU General Public License as published by 16;; the Free Software Foundation; either version 2, or (at your option) 17;; any later version. 18 19;; This file is distributed in the hope that it will be useful, 20;; but WITHOUT ANY WARRANTY; without even the implied warranty of 21;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22;; GNU General Public License for more details. 23 24;; You should have received a copy of the GNU General Public License 25;; along with GNU Emacs; see the file COPYING. If not, write to 26;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 27;; Boston, MA 02111-1307, USA. 28 29;;; Commentary: 30 31;; Basic steps to setup: 32;; 33;; 1. In your .emacs file: 34;; (add-to-list 'load-path "/dir/to/yasnippet.el") 35;; (require 'yasnippet) 36;; 2. Place the `snippets' directory somewhere. E.g: ~/.emacs.d/snippets 37;; 3. In your .emacs file 38;; (setq yas/root-directory "~/.emacs/snippets") 39;; (yas/load-directory yas/root-directory) 40;; 4. To enable the YASnippet menu and tab-trigger expansion 41;; M-x yas/minor-mode 42;; 5. To globally enable the minor mode in *all* buffers 43;; M-x yas/global-mode 44;; 45;; Steps 4. and 5. are optional, you don't have to use the minor 46;; mode to use YASnippet. 47;; 48;; Interesting variables are: 49;; 50;; `yas/root-directory' 51;; 52;; The directory where user-created snippets are to be 53;; stored. Can also be a list of directories that 54;; `yas/reload-all' will use for bulk-reloading snippets. In 55;; that case the first directory the default for storing new 56;; snippets. 57;; 58;; `yas/mode-symbol' 59;; 60;; A local variable that you can set in a hook to override 61;; snippet-lookup based on major mode. It is a a symbol (or 62;; list of symbols) that correspond to subdirectories of 63;; `yas/root-directory' and is used for deciding which 64;; snippets to consider for the active buffer. 65;; 66;; Major commands are: 67;; 68;; M-x yas/expand 69;; 70;; Try to expand snippets before point. In `yas/minor-mode', 71;; this is bound to `yas/trigger-key' which you can customize. 72;; 73;; M-x yas/load-directory 74;; 75;; Prompts you for a directory hierarchy of snippets to load. 76;; 77;; M-x yas/insert-snippet 78;; 79;; Prompts you for possible snippet expansion if that is 80;; possible according to buffer-local and snippet-local 81;; expansion conditions. With prefix argument, ignore these 82;; conditions. 83;; 84;; M-x yas/find-snippets 85;; 86;; Lets you find the snippet files in the correct 87;; subdirectory of `yas/root-directory', according to the 88;; active major mode (if it exists) like 89;; `find-file-other-window'. 90;; 91;; M-x yas/visit-snippet-file 92;; 93;; Prompts you for possible snippet expansions like 94;; `yas/insert-snippet', but instead of expanding it, takes 95;; you directly to the snippet definition's file, if it 96;; exists. 97;; 98;; M-x yas/new-snippet 99;; 100;; Lets you create a new snippet file in the correct 101;; subdirectory of `yas/root-directory', according to the 102;; active major mode. 103;; 104;; M-x yas/load-snippet-buffer 105;; 106;; When editing a snippet, this loads the snippet. This is 107;; bound to "C-c C-c" while in the `snippet-mode' editing 108;; mode. 109;; 110;; M-x yas/tryout-snippet 111;; 112;; When editing a snippet, this opens a new empty buffer, 113;; sets it to the appropriate major mode and inserts the 114;; snippet there, so you can see what it looks like. This is 115;; bound to "C-c C-t" while in `snippet-mode'. 116;; 117;; The `dropdown-list.el' extension is bundled with YASnippet, you 118;; can optionally use it the preferred "prompting method", puting in 119;; your .emacs file, for example: 120;; 121;; (require 'dropdown-list) 122;; (setq yas/prompt-functions '(yas/dropdown-prompt 123;; yas/ido-prompt 124;; yas/completing-prompt)) 125;; 126;; Also check out the customization group 127;; 128;; M-x customize-group RET yasnippet RET 129;; 130;; If you use the customization group to set variables 131;; `yas/root-directory' or `yas/global-mode', make sure the path to 132;; "yasnippet.el" is present in the `load-path' *before* the 133;; `custom-set-variables' is executed in your .emacs file. 134;; 135;; For more information and detailed usage, refer to the project page: 136;; http://code.google.com/p/yasnippet/ 137 138;;; Code: 139 140(require 'cl) 141(require 'assoc) 142(require 'easymenu) 143 144 145;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 146;; User customizable variables 147 148 149(defgroup yasnippet nil 150 "Yet Another Snippet extension" 151 :group 'editing) 152 153;;;###autoload 154(defcustom yas/root-directory nil 155 "Root directory that stores the snippets for each major mode. 156 157If you set this from your .emacs, can also be a list of strings, 158for multiple root directories. If you make this a list, the first 159element is always the user-created snippets directory. Other 160directories are used for bulk reloading of all snippets using 161`yas/reload-all'" 162 :type '(choice (string :tag "Single directory (string)") 163 (repeat :args (string) :tag "List of directories (strings)")) 164 :group 'yasnippet 165 :require 'yasnippet 166 :set #'(lambda (symbol new) 167 (let ((old (and (boundp symbol) 168 (symbol-value symbol)))) 169 (set-default symbol new) 170 (unless (or (not (fboundp 'yas/reload-all)) 171 (equal old new)) 172 (yas/reload-all))))) 173 174(defcustom yas/prompt-functions '(yas/x-prompt 175 yas/dropdown-prompt 176 yas/completing-prompt 177 yas/ido-prompt 178 yas/no-prompt) 179 "Functions to prompt for keys, templates, etc interactively. 180 181These functions are called with the following arguments: 182 183- PROMPT: A string to prompt the user 184 185- CHOICES: a list of strings or objects. 186 187- optional DISPLAY-FN : A function that, when applied to each of 188the objects in CHOICES will return a string. 189 190The return value of any function you put here should be one of 191the objects in CHOICES, properly formatted with DISPLAY-FN (if 192that is passed). 193 194- To signal that your particular style of prompting is 195unavailable at the moment, you can also have the function return 196nil. 197 198- To signal that the user quit the prompting process, you can 199signal `quit' with 200 201 (signal 'quit \"user quit!\")." 202 :type '(repeat function) 203 :group 'yasnippet) 204 205(defcustom yas/indent-line 'auto 206 "Controls indenting applied to a recent snippet expansion. 207 208The following values are possible: 209 210- `fixed' Indent the snippet to the current column; 211 212- `auto' Indent each line of the snippet with `indent-according-to-mode' 213 214Every other value means don't apply any snippet-side indendation 215after expansion (the manual per-line \"$>\" indentation still 216applies)." 217 :type '(choice (const :tag "Nothing" nothing) 218 (const :tag "Fixed" fixed) 219 (const :tag "Auto" auto)) 220 :group 'yasnippet) 221 222(defcustom yas/also-auto-indent-first-line nil 223 "Non-nil means also auto indent first line according to mode. 224 225Naturally this is only valid when `yas/indent-line' is `auto'" 226 :type 'boolean 227 :group 'yasnippet) 228 229(defcustom yas/snippet-revival t 230 "Non-nil means re-activate snippet fields after undo/redo." 231 :type 'boolean 232 :group 'yasnippet) 233 234(defcustom yas/trigger-key "TAB" 235 "The key bound to `yas/expand' when function `yas/minor-mode' is active. 236 237Value is a string that is converted to the internal Emacs key 238representation using `read-kbd-macro'." 239 :type 'string 240 :group 'yasnippet 241 :set #'(lambda (symbol key) 242 (let ((old (and (boundp symbol) 243 (symbol-value symbol)))) 244 (set-default symbol key) 245 ;; On very first loading of this defcustom, 246 ;; `yas/trigger-key' is *not* loaded. 247 (if (fboundp 'yas/trigger-key-reload) 248 (yas/trigger-key-reload old))))) 249 250(defcustom yas/next-field-key '("TAB" "<tab>") 251 "The key to navigate to next field when a snippet is active. 252 253Value is a string that is converted to the internal Emacs key 254representation using `read-kbd-macro'. 255 256Can also be a list of strings." 257 :type '(choice (string :tag "String") 258 (repeat :args (string) :tag "List of strings")) 259 :group 'yasnippet 260 :set #'(lambda (symbol val) 261 (set-default symbol val) 262 (if (fboundp 'yas/init-yas-in-snippet-keymap) 263 (yas/init-yas-in-snippet-keymap)))) 264 265 266(defcustom yas/prev-field-key '("<backtab>" "<S-tab>") 267 "The key to navigate to previous field when a snippet is active. 268 269Value is a string that is converted to the internal Emacs key 270representation using `read-kbd-macro'. 271 272Can also be a list of strings." 273 :type '(choice (string :tag "String") 274 (repeat :args (string) :tag "List of strings")) 275 :group 'yasnippet 276 :set #'(lambda (symbol val) 277 (set-default symbol val) 278 (if (fboundp 'yas/init-yas-in-snippet-keymap) 279 (yas/init-yas-in-snippet-keymap)))) 280 281(defcustom yas/skip-and-clear-key "C-d" 282 "The key to clear the currently active field. 283 284Value is a string that is converted to the internal Emacs key 285representation using `read-kbd-macro'. 286 287Can also be a list of strings." 288 :type '(choice (string :tag "String") 289 (repeat :args (string) :tag "List of strings")) 290 :group 'yasnippet 291 :set #'(lambda (symbol val) 292 (set-default symbol val) 293 (if (fboundp 'yas/init-yas-in-snippet-keymap) 294 (yas/init-yas-in-snippet-keymap)))) 295 296(defcustom yas/triggers-in-field nil 297 "If non-nil, `yas/next-field-key' can trigger stacked expansions. 298 299Otherwise, `yas/next-field-key' just tries to move on to the next 300field" 301 :type 'boolean 302 :group 'yasnippet) 303 304(defcustom yas/fallback-behavior 'call-other-command 305 "How to act when `yas/trigger-key' does *not* expand a snippet. 306 307- `call-other-command' means try to temporarily disable YASnippet 308 and call the next command bound to `yas/trigger-key'. 309 310- nil or the symbol `return-nil' mean do nothing. (and 311 `yas/expand-returns' nil) 312 313- A lisp form (apply COMMAND . ARGS) means interactively call 314 COMMAND, if ARGS is non-nil, call COMMAND non-interactively 315 with ARGS as arguments." 316 :type '(choice (const :tag "Call previous command" call-other-command) 317 (const :tag "Do nothing" return-nil)) 318 :group 'yasnippet) 319(make-variable-buffer-local 'yas/fallback-behavior) 320 321(defcustom yas/choose-keys-first nil 322 "If non-nil, prompt for snippet key first, then for template. 323 324Otherwise prompts for all possible snippet names. 325 326This affects `yas/insert-snippet' and `yas/visit-snippet-file'." 327 :type 'boolean 328 :group 'yasnippet) 329 330(defcustom yas/choose-tables-first nil 331 "If non-nil, and multiple eligible snippet tables, prompts user for tables first. 332 333Otherwise, user chooses between the merging together of all 334eligible tables. 335 336This affects `yas/insert-snippet', `yas/visit-snippet-file'" 337 :type 'boolean 338 :group 'yasnippet) 339 340(defcustom yas/use-menu 'real-modes 341 "Display a YASnippet menu in the menu bar. 342 343When non-nil, submenus for each snippet table will be listed 344under the menu \"Yasnippet\". 345 346- If set to `real-modes' only submenus whose name more or less 347corresponds to a major mode are listed. 348 349- If set to `abbreviate', only the current major-mode 350menu and the modes set in `yas/mode-symbol' are listed. 351 352Any other non-nil value, every submenu is listed." 353 :type '(choice (const :tag "Full" t) 354 (const :tag "Real modes only" real-modes) 355 (const :tag "Abbreviate" abbreviate)) 356 :group 'yasnippet) 357 358(defcustom yas/trigger-symbol " =>" 359 "The text that will be used in menu to represent the trigger." 360 :type 'string 361 :group 'yasnippet) 362 363(defcustom yas/wrap-around-region nil 364 "If non-nil, snippet expansion wraps around selected region. 365 366The wrapping occurs just before the snippet's exit marker. This 367can be overriden on a per-snippet basis." 368 :type 'boolean 369 :group 'yasnippet) 370 371(defcustom yas/good-grace t 372 "If non-nil, don't raise errors in inline elisp evaluation. 373 374An error string \"[yas] error\" is returned instead." 375 :type 'boolean 376 :group 'yasnippet) 377 378(defcustom yas/ignore-filenames-as-triggers nil 379 "If non-nil, don't derive tab triggers from filenames. 380 381This means a snippet without a \"# key:'\ directive wont have a 382tab trigger." 383 :type 'boolean 384 :group 'yasnippet) 385 386(defcustom yas/visit-from-menu nil 387 "If non-nil visit snippets's files from menu, instead of expanding them. 388 389This cafn only work when snippets are loaded from files." 390 :type 'boolean 391 :group 'yasnippet) 392 393(defface yas/field-highlight-face 394 '((((class color) (background light)) (:background "DarkSeaGreen1")) 395 (t (:background "DimGrey"))) 396 "The face used to highlight the currently active field of a snippet" 397 :group 'yasnippet) 398 399(defface yas/field-debug-face 400 '() 401 "The face used for debugging some overlays normally hidden" 402 :group 'yasnippet) 403 404 405;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 406;; User can also customize the next defvars 407(defun yas/define-some-keys (keys keymap definition) 408 "Bind KEYS to DEFINITION in KEYMAP, read with `read-kbd-macro'." 409 (let ((keys (or (and (listp keys) keys) 410 (list keys)))) 411 (dolist (key keys) 412 (define-key keymap (read-kbd-macro key) definition)))) 413 414(defvar yas/keymap 415 (let ((map (make-sparse-keymap))) 416 (mapc #'(lambda (binding) 417 (yas/define-some-keys (car binding) map (cdr binding))) 418 `((,yas/next-field-key . yas/next-field-or-maybe-expand) 419 (,yas/prev-field-key . yas/prev-field) 420 ("C-g" . yas/abort-snippet) 421 (,yas/skip-and-clear-key . yas/skip-and-clear-or-delete-char))) 422 map) 423 "The keymap active while a snippet expansion is in progress.") 424 425(defvar yas/key-syntaxes (list "w" "w_" "w_." "^ ") 426 "A list of syntax of a key. This list is tried in the order 427to try to find a key. For example, if the list is '(\"w\" \"w_\"). 428And in emacs-lisp-mode, where \"-\" has the syntax of \"_\": 429 430foo-bar 431 432will first try \"bar\", if not found, then \"foo-bar\" is tried.") 433 434(defvar yas/after-exit-snippet-hook 435 '() 436 "Hooks to run after a snippet exited. 437 438The hooks will be run in an environment where some variables bound to 439proper values: 440 441`yas/snippet-beg' : The beginning of the region of the snippet. 442 443`yas/snippet-end' : Similar to beg. 444 445Attention: These hooks are not run when exiting nested/stackd snippet expansion!") 446 447(defvar yas/before-expand-snippet-hook 448 '() 449 "Hooks to run just before expanding a snippet.") 450 451(defvar yas/buffer-local-condition 452 '(if (and (not (bobp)) 453 (or (equal 'font-lock-comment-face 454 (get-char-property (1- (point)) 455 'face)) 456 (equal 'font-lock-string-face 457 (get-char-property (1- (point)) 458 'face)))) 459 '(require-snippet-condition . force-in-comment) 460 t) 461 "Snippet expanding condition. 462 463This variable is a lisp form: 464 465 * If it evaluates to nil, no snippets can be expanded. 466 467 * If it evaluates to the a cons (require-snippet-condition 468 . REQUIREMENT) 469 470 * Snippets bearing no \"# condition:\" directive are not 471 considered 472 473 * Snippets bearing conditions that evaluate to nil (or 474 produce an error) won't be onsidered. 475 476 * If the snippet has a condition that evaluates to non-nil 477 RESULT: 478 479 * If REQUIREMENT is t, the snippet is considered 480 481 * If REQUIREMENT is `eq' RESULT, the snippet is 482 considered 483 484 * Otherwise, the snippet is not considered. 485 486 * If it evaluates to the symbol 'always, all snippets are 487 considered for expansion, regardless of any conditions. 488 489 * If it evaluates to t or some other non-nil value 490 491 * Snippet bearing no conditions, or conditions that 492 evaluate to non-nil, are considered for expansion. 493 494 * Otherwise, the snippet is not considered. 495 496Here's an example preventing snippets from being expanded from 497inside comments, in `python-mode' only, with the exception of 498snippets returning the symbol 'force-in-comment in their 499conditions. 500 501 (add-hook 'python-mode-hook 502 '(lambda () 503 (setq yas/buffer-local-condition 504 '(if (python-in-string/comment) 505 '(require-snippet-condition . force-in-comment) 506 t)))) 507 508The default value is similar, it filters out potential snippet 509expansions inside comments and string literals, unless the 510snippet itself contains a condition that returns the symbol 511`force-in-comment'.") 512(make-variable-buffer-local 'yas/buffer-local-condition) 513 514 515;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 516;; Internal variables 517 518(defvar yas/version "0.6.1b") 519 520(defvar yas/menu-table (make-hash-table) 521 "A hash table of MAJOR-MODE symbols to menu keymaps.") 522 523(defvar yas/active-keybindings nil 524 "A list of cons (KEYMAP . KEY) setup from defining snippets.") 525 526(defvar yas/known-modes 527 '(ruby-mode rst-mode markdown-mode) 528 "A list of mode which is well known but not part of emacs.") 529 530(defvar yas/escaped-characters 531 '(?\\ ?` ?' ?$ ?} ) 532 "List of characters which *might* need to be escaped.") 533 534(defconst yas/field-regexp 535 "${\\([0-9]+:\\)?\\([^}]*\\)}" 536 "A regexp to *almost* recognize a field.") 537 538(defconst yas/multi-dollar-lisp-expression-regexp 539 "$+[ \t\n]*\\(([^)]*)\\)" 540 "A regexp to *almost* recognize a \"$(...)\" expression.") 541 542(defconst yas/backquote-lisp-expression-regexp 543 "`\\([^`]*\\)`" 544 "A regexp to recognize a \"`lisp-expression`\" expression." ) 545 546(defconst yas/transform-mirror-regexp 547 "${\\(?:\\([0-9]+\\):\\)?$\\([ \t\n]*([^}]*\\)" 548 "A regexp to *almost* recognize a mirror with a transform.") 549 550(defconst yas/simple-mirror-regexp 551 "$\\([0-9]+\\)" 552 "A regexp to recognize a simple mirror.") 553 554(defvar yas/snippet-id-seed 0 555 "Contains the next id for a snippet.") 556 557(defun yas/snippet-next-id () 558 (let ((id yas/snippet-id-seed)) 559 (incf yas/snippet-id-seed) 560 id)) 561 562 563;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 564;; Minor mode stuff 565 566;; XXX: `last-buffer-undo-list' is somehow needed in Carbon Emacs for MacOSX 567(defvar last-buffer-undo-list nil) 568 569(defvar yas/minor-mode-menu nil 570 "Holds the YASnippet menu") 571 572(defun yas/init-minor-keymap () 573 (let ((map (make-sparse-keymap))) 574 (easy-menu-define yas/minor-mode-menu 575 map 576 "Menu used when YAS/minor-mode is active." 577 '("YASnippet" 578 "----" 579 ["Expand trigger" yas/expand 580 :help "Possibly expand tab trigger before point"] 581 ["Insert at point..." yas/insert-snippet 582 :help "Prompt for an expandable snippet and expand it at point"] 583 ["New snippet..." yas/new-snippet 584 :help "Create a new snippet in an appropriate directory"] 585 ["Visit snippet file..." yas/visit-snippet-file 586 :help "Prompt for an expandable snippet and find its file"] 587 ["Find snippets..." yas/find-snippets 588 :help "Invoke `find-file' in the appropriate snippet directory"] 589 "----" 590 ("Snippet menu behaviour" 591 ["Visit snippets" (setq yas/visit-from-menu t) 592 :help "Visit snippets from the menu" 593 :active t :style radio :selected yas/visit-from-menu] 594 ["Expand snippets" (setq yas/visit-from-menu nil) 595 :help "Expand snippets from the menu" 596 :active t :style radio :selected (not yas/visit-from-menu)] 597 "----" 598 ["Show \"Real\" modes only" (setq yas/use-menu 'real-modes) 599 :help "Show snippet submenus for modes that appear to be real major modes" 600 :active t :style radio :selected (eq yas/use-menu 'real-modes)] 601 ["Show all modes" (setq yas/use-menu 't) 602 :help "Show one snippet submenu for each loaded table" 603 :active t :style radio :selected (eq yas/use-menu 't)] 604 ["Abbreviate according to current mode" (setq yas/use-menu 'abbreviate) 605 :help "Show only snippet submenus for the current active modes" 606 :active t :style radio :selected (eq yas/use-menu 'abbreviate)]) 607 ("Indenting" 608 ["Auto" (setq yas/indent-line 'auto) 609 :help "Indent each line of the snippet with `indent-according-to-mode'" 610 :active t :style radio :selected (eq yas/indent-line 'auto)] 611 ["Fixed" (setq yas/indent-line 'fixed) 612 :help "Indent the snippet to the current column" 613 :active t :style radio :selected (eq yas/indent-line 'fixed)] 614 ["None" (setq yas/indent-line 'none) 615 :help "Don't apply any particular snippet indentation after expansion" 616 :active t :style radio :selected (not (member yas/indent-line '(fixed auto)))] 617 "----" 618 ["Also auto indent first line" (setq yas/also-auto-indent-first-line 619 (not yas/also-auto-indent-first-line)) 620 :help "When auto-indenting also, auto indent the first line menu" 621 :active (eq yas/indent-line 'auto) 622 :style toggle :selected yas/also-auto-indent-first-line] 623 ) 624 ("Prompting method" 625 ["System X-widget" (setq yas/prompt-functions 626 (cons 'yas/x-prompt 627 (remove 'yas/x-prompt 628 yas/prompt-functions))) 629 :help "Use your windowing system's (gtk, mac, windows, etc...) default menu" 630 :active t :style radio :selected (eq (car yas/prompt-functions) 631 'yas/x-prompt)] 632 ["Dropdown-list" (setq yas/prompt-functions 633 (cons 'yas/dropdown-prompt 634 (remove 'yas/dropdown-prompt 635 yas/prompt-functions))) 636 :help "Use a special dropdown list" 637 :active t :style radio :selected (eq (car yas/prompt-functions) 638 'yas/dropdown-prompt)] 639 ["Ido" (setq yas/prompt-functions 640 (cons 'yas/ido-prompt 641 (remove 'yas/ido-prompt 642 yas/prompt-functions))) 643 :help "Use an ido-style minibuffer prompt" 644 :active t :style radio :selected (eq (car yas/prompt-functions) 645 'yas/ido-prompt)] 646 ["Completing read" (setq yas/prompt-functions 647 (cons 'yas/completing-prompt 648 (remove 'yas/completing-prompt-prompt 649 yas/prompt-functions))) 650 :help "Use a normal minibuffer prompt" 651 :active t :style radio :selected (eq (car yas/prompt-functions) 652 'yas/completing-prompt-prompt)] 653 ) 654 ("Misc" 655 ["Wrap region in exit marker" 656 (setq yas/wrap-around-region 657 (not yas/wrap-around-region)) 658 :help "If non-nil automatically wrap the selected text in the $0 snippet exit" 659 :style toggle :selected yas/wrap-around-region] 660 ["Allow stacked expansions " 661 (setq yas/triggers-in-field 662 (not yas/triggers-in-field)) 663 :help "If non-nil allow snippets to be triggered inside other snippet fields" 664 :style toggle :selected yas/triggers-in-field] 665 ["Revive snippets on undo " 666 (setq yas/snippet-revival 667 (not yas/snippet-revival)) 668 :help "If non-nil allow snippets to become active again after undo" 669 :style toggle :selected yas/snippet-revival] 670 ["Good grace " 671 (setq yas/good-grace 672 (not yas/good-grace)) 673 :help "If non-nil don't raise errors in bad embedded eslip in snippets" 674 :style toggle :selected yas/good-grace] 675 ["Ignore filenames as triggers" 676 (setq yas/ignore-filenames-as-triggers 677 (not yas/ignore-filenames-as-triggers)) 678 :help "If non-nil don't derive tab triggers from filenames" 679 :style toggle :selected yas/ignore-filenames-as-triggers] 680 ) 681 "----" 682 ["Load snippets..." yas/load-directory 683 :help "Load snippets from a specific directory"] 684 ["Reload everything" yas/reload-all 685 :help "Cleanup stuff, reload snippets, rebuild menus"] 686 ["About" yas/about 687 :help "Display some information about YASsnippet"])) 688 ;; Now for the stuff that has direct keybindings 689 ;; 690 (define-key map "\C-c&\C-s" 'yas/insert-snippet) 691 (define-key map "\C-c&\C-n" 'yas/new-snippet) 692 (define-key map "\C-c&\C-v" 'yas/visit-snippet-file) 693 (define-key map "\C-c&\C-f" 'yas/find-snippets) 694 map)) 695 696(defvar yas/minor-mode-map (yas/init-minor-keymap) 697 "The keymap used when `yas/minor-mode' is active.") 698 699(defun yas/trigger-key-reload (&optional unbind-key) 700 "Rebind `yas/expand' to the new value of `yas/trigger-key'. 701 702With optional UNBIND-KEY, try to unbind that key from 703`yas/minor-mode-map'." 704 (when (and unbind-key 705 (stringp unbind-key) 706 (not (string= unbind-key ""))) 707 (define-key yas/minor-mode-map (read-kbd-macro unbind-key) nil)) 708 (when (and yas/trigger-key 709 (stringp yas/trigger-key) 710 (not (string= yas/trigger-key ""))) 711 (define-key yas/minor-mode-map (read-kbd-macro yas/trigger-key) 'yas/expand))) 712 713;;;###autoload 714(define-minor-mode yas/minor-mode 715 "Toggle YASnippet mode. 716 717When YASnippet mode is enabled, the `tas/trigger-key' key expands 718snippets of code depending on the mode. 719 720With no argument, this command toggles the mode. 721positive prefix argument turns on the mode. 722Negative prefix argument turns off the mode. 723 724You can customize the key through `yas/trigger-key'. 725 726Key bindings: 727\\{yas/minor-mode-map}" 728 nil 729 ;; The indicator for the mode line. 730 " yas" 731 :group 'yasnippet 732 (when yas/minor-mode 733 (yas/trigger-key-reload) 734 ;; load all snippets definitions unless we still don't have a 735 ;; root-directory or some snippets have already been loaded. 736 (unless (or (null yas/root-directory) 737 (> (hash-table-count yas/snippet-tables) 0)) 738 (yas/reload-all)))) 739 740(defvar yas/dont-activate #'(lambda () 741 (and yas/root-directory 742 (null (yas/get-snippet-tables)))) 743 "If non-nil don't let `yas/minor-mode-on' active yas for this buffer. 744 745`yas/minor-mode-on' is usually called by `yas/global-mode' so 746this effectively lets you define exceptions to the \"global\" 747behaviour.") 748(make-variable-buffer-local 'yas/dont-activate) 749 750 751(defun yas/minor-mode-on () 752 "Turn on YASnippet minor mode. 753 754Do this unless `yas/dont-activate' is t or the function 755`yas/get-snippet-tables' (which see), returns an empty list." 756 (interactive) 757 (unless (or (and (functionp yas/dont-activate) 758 (funcall yas/dont-activate)) 759 (and (not (functionp yas/dont-activate)) 760 yas/dont-activate)) 761 (yas/minor-mode 1))) 762 763(defun yas/minor-mode-off () 764 "Turn off YASnippet minor mode." 765 (interactive) 766 (yas/minor-mode -1)) 767 768(define-globalized-minor-mode yas/global-mode yas/minor-mode yas/minor-mode-on 769 :group 'yasnippet 770 :require 'yasnippet) 771 772;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 773;; Major mode stuff 774;; 775(defvar yas/font-lock-keywords 776 (append '(("^#.*$" . font-lock-comment-face)) 777 lisp-font-lock-keywords 778 lisp-font-lock-keywords-1 779 lisp-font-lock-keywords-2 780 '(("$\\([0-9]+\\)" 781 (0 font-lock-keyword-face) 782 (1 font-lock-string-face t)) 783 ("${\\([0-9]+\\):?" 784 (0 font-lock-keyword-face) 785 (1 font-lock-warning-face t)) 786 ("${" font-lock-keyword-face) 787 ("$[0-9]+?" font-lock-preprocessor-face) 788 ("\\(\\$(\\)" 1 font-lock-preprocessor-face) 789 ("}" 790 (0 font-lock-keyword-face))))) 791 792(defun yas/init-major-keymap () 793 (let ((map (make-sparse-keymap))) 794 (easy-menu-define nil 795 map 796 "Menu used when snippet-mode is active." 797 (cons "Snippet" 798 (mapcar #'(lambda (ent) 799 (when (third ent) 800 (define-key map (third ent) (second ent))) 801 (vector (first ent) (second ent) t)) 802 (list 803 (list "Load this snippet" 'yas/load-snippet-buffer "\C-c\C-c") 804 (list "Try out this snippet" 'yas/tryout-snippet "\C-c\C-t"))))) 805 map)) 806 807(defvar snippet-mode-map 808 (yas/init-major-keymap) 809 "The keymap used when `snippet-mode' is active") 810 811 812(define-derived-mode snippet-mode text-mode "Snippet" 813 "A mode for editing yasnippets" 814 (set-syntax-table (standard-syntax-table)) 815 (setq font-lock-defaults '(yas/font-lock-keywords)) 816 (set (make-local-variable 'require-final-newline) nil) 817 (use-local-map snippet-mode-map)) 818 819;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 820;; Internal structs for template management 821 822(defstruct (yas/template (:constructor yas/make-template 823 (content name condition expand-env file keybinding))) 824 "A template for a snippet." 825 content 826 name 827 condition 828 expand-env 829 file 830 keybinding) 831 832(defvar yas/snippet-tables (make-hash-table) 833 "A hash table of MAJOR-MODE symbols to `yas/snippet-table' objects.") 834 835(defstruct (yas/snippet-table (:constructor yas/make-snippet-table (name))) 836 "A table to store snippets for a particular mode. 837 838Has the following fields: 839 840`yas/snippet-table-name' 841 842 A symbol normally corresponding to a major mode, but can also be 843 a pseudo major-mode to be referenced in `yas/mode-symbol', for 844 example. 845 846`yas/snippet-table-hash' 847 848 A hash table the key is a string (the snippet key) and the 849 value is yet another hash of (NAME TEMPLATE), where NAME is the 850 snippet name and TEMPLATE is a `yas/template' object name. 851 852`yas/snippet-table-parents' 853 854 A list of tables considered parents of this table: i.e. when 855 searching for expansions they are searched as well." 856 name 857 (hash (make-hash-table :test 'equal)) 858 (parents nil)) 859 860(defvar yas/better-guess-for-replacements nil 861 "If non-nil `yas/store' better guess snippet replacements.") 862 863(defun yas/store (table name key template) 864 "Store a snippet template in the TABLE." 865 866 ;; This is dones by searching twice: 867 ;; 868 ;; * Try to get the existing namehash from TABLE using key. 869 ;; 870 ;; * Try to get the existing namehash from by searching the *whole* 871 ;; snippet table for NAME. This is becuase they user might have 872 ;; changed the key and that can no longer be used to locate the 873 ;; previous `yas/template-structure'. 874 ;; 875 ;; * If that returns nothing, oh well... 876 ;; 877 (dolist (existing-namehash (remove nil (list (gethash key (yas/snippet-table-hash table)) 878 (when yas/better-guess-for-replacements 879 (let (a) 880 (maphash #'(lambda (key namehash) 881 (when (gethash name namehash) 882 (setq a namehash))) 883 (yas/snippet-table-hash table)) 884 a))))) 885 (let ((existing-template (gethash name existing-namehash))) 886 (when existing-template 887 ;; Remove the existing keybinding 888 (when (yas/template-keybinding existing-template) 889 (define-key 890 (symbol-value (first (yas/template-keybinding existing-template))) 891 (second (yas/template-keybinding existing-template)) 892 nil) 893 (setq yas/active-keybindings 894 (delete (yas/template-keybinding existing-template) 895 yas/active-keybindings))) 896 ;; Remove the (name . template) mapping from existing-namehash. 897 (remhash name existing-namehash)))) 898 ;; Now store the new template independent of the previous steps. 899 ;; 900 (puthash name 901 template 902 (or (gethash key 903 (yas/snippet-table-hash table)) 904 (puthash key 905 (make-hash-table :test 'equal) 906 (yas/snippet-table-hash table))))) 907 908(defun yas/fetch (table key) 909 "Fetch a snippet binding to KEY from TABLE." 910 (let* ((keyhash (yas/snippet-table-hash table)) 911 (namehash (and keyhash (gethash key keyhash)))) 912 (when namehash 913 (yas/filter-templates-by-condition 914 (let (alist) 915 (maphash #'(lambda (k v) 916 (push (cons k v) alist)) 917 namehash) 918 alist))))) 919 920 921;; Filtering/condition logic 922 923(defun yas/eval-condition (condition) 924 (condition-case err 925 (save-excursion 926 (save-restriction 927 (save-match-data 928 (eval condition)))) 929 (error (progn 930 (message (format "[yas] error in condition evaluation: %s" 931 (error-message-string err))) 932 nil)))) 933 934 935(defun yas/filter-templates-by-condition (templates) 936 "Filter the templates using the applicable condition. 937 938TEMPLATES is a list of cons (NAME . TEMPLATE) where NAME is a 939string and TEMPLATE is a `yas/template' structure. 940 941This function implements the rules described in 942`yas/buffer-local-condition'. See that variables documentation." 943 (let ((requirement (yas/require-template-specific-condition-p))) 944 (if (eq requirement 'always) 945 templates 946 (remove-if-not #'(lambda (pair) 947 (yas/template-can-expand-p (yas/template-condition (cdr pair)) requirement)) 948 templates)))) 949 950(defun yas/require-template-specific-condition-p () 951 "Decides if this buffer requests/requires snippet-specific 952conditions to filter out potential expansions." 953 (if (eq 'always yas/buffer-local-condition) 954 'always 955 (let ((local-condition (or (and (consp yas/buffer-local-condition) 956 (yas/eval-condition yas/buffer-local-condition)) 957 yas/buffer-local-condition))) 958 (when local-condition 959 (if (eq local-condition t) 960 t 961 (and (consp local-condition) 962 (eq 'require-snippet-condition (car local-condition)) 963 (symbolp (cdr local-condition)) 964 (cdr local-condition))))))) 965 966(defun yas/template-can-expand-p (condition &optional requirement) 967 "Evaluates CONDITION and REQUIREMENT and returns a boolean" 968 (let* ((requirement (or requirement 969 (yas/require-template-specific-condition-p))) 970 (result (or (null condition) 971 (yas/eval-condition 972 (condition-case err 973 (read condition) 974 (error (progn 975 (message (format "[yas] error reading condition: %s" 976 (error-message-string err)))) 977 nil)))))) 978 (cond ((eq requirement t) 979 result) 980 (t 981 (eq requirement result))))) 982 983(defun yas/snippet-table-get-all-parents (table) 984 (let ((parents (yas/snippet-table-parents table))) 985 (when parents 986 (append (copy-list parents) 987 (mapcan #'yas/snippet-table-get-all-parents parents))))) 988 989(defun yas/snippet-table-templates (table) 990 (when table 991 (let ((acc (list))) 992 (maphash #'(lambda (key namehash) 993 (maphash #'(lambda (name template) 994 (push (cons name template) acc)) 995 namehash)) 996 (yas/snippet-table-hash table)) 997 (yas/filter-templates-by-condition acc)))) 998 999(defun yas/current-key () 1000 "Get the key under current position. A key is used to find 1001the template of a snippet in the current snippet-table." 1002 (let ((start (point)) 1003 (end (point)) 1004 (syntaxes yas/key-syntaxes) 1005 syntax 1006 done 1007 templates) 1008 (while (and (not done) syntaxes) 1009 (setq syntax (car syntaxes)) 1010 (setq syntaxes (cdr syntaxes)) 1011 (save-excursion 1012 (skip-syntax-backward syntax) 1013 (setq start (point))) 1014 (setq templates 1015 (mapcan #'(lambda (table) 1016 (yas/fetch table (buffer-substring-no-properties start end))) 1017 (yas/get-snippet-tables))) 1018 (if templates 1019 (setq done t) 1020 (setq start end))) 1021 (list templates 1022 start 1023 end))) 1024 1025 1026(defun yas/snippet-table-all-keys (table) 1027 (when table 1028 (let ((acc)) 1029 (maphash #'(lambda (key templates) 1030 (when (yas/filter-templates-by-condition templates) 1031 (push key acc))) 1032 (yas/snippet-table-hash table)) 1033 acc))) 1034 1035 1036;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1037;; Internal functions 1038 1039(defun yas/real-mode? (mode) 1040 "Try to find out if MODE is a real mode. The MODE bound to 1041a function (like `c-mode') is considered real mode. Other well 1042known mode like `ruby-mode' which is not part of Emacs might 1043not bound to a function until it is loaded. So yasnippet keeps 1044a list of modes like this to help the judgement." 1045 (or (fboundp mode) 1046 (find mode yas/known-modes))) 1047 1048(defun yas/read-and-eval-string (string) 1049 ;; TODO: This is a possible optimization point, the expression could 1050 ;; be stored in cons format instead of string, 1051 "Evaluate STRING and convert the result to string." 1052 (let ((retval (catch 'yas/exception 1053 (condition-case err 1054 (save-excursion 1055 (save-restriction 1056 (save-match-data 1057 (widen) 1058 (let ((result (eval (read string)))) 1059 (when result 1060 (format "%s" result)))))) 1061 (error (if yas/good-grace 1062 "[yas] elisp error!" 1063 (error (format "[yas] elisp error: %s" 1064 (error-message-string err))))))))) 1065 (when (and (consp retval) 1066 (eq 'yas/exception (car retval))) 1067 (error (cdr retval))) 1068 retval)) 1069 1070(defvar yas/mode-symbol nil 1071 "If non-nil, lookup snippets using this instead of `major-mode'.") 1072(make-variable-buffer-local 'yas/mode-symbol) 1073 1074(defun yas/snippet-table-get-create (mode) 1075 "Get the snippet table corresponding to MODE. 1076 1077Optional DIRECTORY gets recorded as the default directory to 1078search for snippet files if the retrieved/created table didn't 1079already have such a property." 1080 (let ((table (gethash mode 1081 yas/snippet-tables))) 1082 (unless table 1083 (setq table (yas/make-snippet-table (symbol-name mode))) 1084 (puthash mode table yas/snippet-tables)) 1085 table)) 1086 1087(defun yas/get-snippet-tables (&optional mode-symbol dont-search-parents) 1088 "Get snippet tables for current buffer. 1089 1090Return a list of 'yas/snippet-table' objects indexed by mode. 1091 1092The modes are tried in this order: optional MODE-SYMBOL, then 1093`yas/mode-symbol', then `major-mode' then, unless 1094DONT-SEARCH-PARENTS is non-nil, the guessed parent mode of either 1095MODE-SYMBOL or `major-mode'. 1096 1097Guessing is done by looking up the MODE-SYMBOL's 1098`derived-mode-parent' property, see also `derived-mode-p'." 1099 (let ((mode-tables 1100 (mapcar #'(lambda (mode) 1101 (gethash mode yas/snippet-tables)) 1102 (append (list mode-symbol) 1103 (if (listp yas/mode-symbol) 1104 yas/mode-symbol 1105 (list yas/mode-symbol)) 1106 (list major-mode 1107 (and (not dont-search-parents) 1108 (get (or mode-symbol major-mode) 1109 'derived-mode-parent)))))) 1110 (all-tables)) 1111 (dolist (table (remove nil mode-tables)) 1112 (push table all-tables) 1113 (nconc all-tables (yas/snippet-table-get-all-parents table))) 1114 (remove-duplicates all-tables))) 1115 1116(defun yas/menu-keymap-get-create (mode) 1117 "Get the menu keymap correspondong to MODE." 1118 (or (gethash mode yas/menu-table) 1119 (puthash mode (make-sparse-keymap) yas/menu-table))) 1120 1121;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1122;;; Template-related and snippet loading functions 1123 1124(defun yas/parse-template (&optional file) 1125 "Parse the template in the current buffer. 1126 1127Optional FILE is the absolute file name of the file being 1128parsed. 1129 1130Return a snippet-definition, i.e. a list 1131 1132 (KEY TEMPLATE NAME CONDITION GROUP VARS FILE KEYBINDING) 1133 1134If the buffer contains a line of \"# --\" then the contents 1135above this line are ignored. Variables can be set above this 1136line through the syntax: 1137 1138#name : value 1139 1140Here's a list of currently recognized variables: 1141 1142 * name 1143 * contributor 1144 * condition 1145 * key 1146 * group 1147 * expand-env 1148 1149#name: #include \"...\" 1150# -- 1151#include \"$1\"" 1152 ;; 1153 ;; 1154 (goto-char (point-min)) 1155 (let* ((name (and file 1156 (file-name-nondirectory file))) 1157 (key (unless yas/ignore-filenames-as-triggers 1158 (and name 1159 (file-name-sans-extension name)))) 1160 template 1161 bound 1162 condition 1163 (group (and file 1164 (yas/calculate-group file))) 1165 expand-env 1166 binding) 1167 (if (re-search-forward "^# --\n" nil t) 1168 (progn (setq template 1169 (buffer-substring-no-properties (point) 1170 (point-max))) 1171 (setq bound (point)) 1172 (goto-char (point-min)) 1173 (while (re-search-forward "^# *\\([^ ]+?\\) *: *\\(.*\\)$" bound t) 1174 (when (string= "name" (match-string-no-properties 1)) 1175 (setq name (match-string-no-properties 2))) 1176 (when (string= "condition" (match-string-no-properties 1)) 1177 (setq condition (match-string-no-properties 2))) 1178 (when (string= "group" (match-string-no-properties 1)) 1179 (setq group (match-string-no-properties 2))) 1180 (when (string= "expand-env" (match-string-no-properties 1)) 1181 (setq expand-env (match-string-no-properties 2))) 1182 (when (string= "key" (match-string-no-properties 1)) 1183 (setq key (match-string-no-properties 2))) 1184 (when (string= "binding" (match-string-no-properties 1)) 1185 (setq binding (match-string-no-properties 2))))) 1186 (setq template 1187 (buffer-substring-no-properties (point-min) (point-max)))) 1188 (list key template name condition group expand-env file binding))) 1189 1190(defun yas/calculate-group (file) 1191 "Calculate the group for snippet file path FILE." 1192 (let* ((dominating-dir (locate-dominating-file file 1193 ".yas-make-groups")) 1194 (extra-path (and dominating-dir 1195 (replace-regexp-in-string (concat "^" 1196 (expand-file-name dominating-dir)) 1197 "" 1198 (expand-file-name file)))) 1199 (extra-dir (and extra-path 1200 (file-name-directory extra-path))) 1201 (group (and extra-dir 1202 (replace-regexp-in-string "/" 1203 "." 1204 (directory-file-name extra-dir))))) 1205 group)) 1206 1207;; (defun yas/glob-files (directory &optional recurse-p append) 1208;; "Returns files under DIRECTORY ignoring dirs and hidden files. 1209 1210;; If RECURSE in non-nil, do that recursively." 1211;; (let (ret 1212;; (default-directory directory)) 1213;; (dolist (entry (directory-files ".")) 1214;; (cond ((or (string-match "^\\." 1215;; (file-name-nondirectory entry)) 1216;; (string-match "~$" 1217;; (file-name-nondirectory entry))) 1218;; nil) 1219;; ((and recurse-p 1220;; (file-directory-p entry)) 1221;; (setq ret (nconc ret 1222;; (yas/glob-files (expand-file-name entry) 1223;; recurse-p 1224;; (if append 1225;; (concat append "/" entry) 1226;; entry))))) 1227;; ((file-directory-p entry) 1228;; nil) 1229;; (t 1230;; (push (if append 1231;; (concat append "/" entry) 1232;; entry) ret)))) 1233;; ret)) 1234 1235(defun yas/subdirs (directory &optional file?) 1236 "Return subdirs or files of DIRECTORY according to FILE?." 1237 (remove-if (lambda (file) 1238 (or (string-match "^\\." 1239 (file-name-nondirectory file)) 1240 (string-match "~$" 1241 (file-name-nondirectory file)) 1242 (if file? 1243 (file-directory-p file) 1244 (not (file-directory-p file))))) 1245 (directory-files directory t))) 1246 1247(defun yas/make-menu-binding (template) 1248 `(lambda () (interactive) (yas/expand-or-visit-from-menu ,template))) 1249 1250(defun yas/expand-or-visit-from-menu (template) 1251 (if yas/visit-from-menu 1252 (yas/visit-snippet-file-1 template) 1253 (let ((where (if mark-active 1254 (cons (region-beginning) (region-end)) 1255 (cons (point) (point))))) 1256 (yas/expand-snippet (yas/template-content template) 1257 (car where) 1258 (cdr where))))) 1259 1260;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1261;; Popping up for keys and templates 1262;; 1263(defun yas/prompt-for-template (templates &optional prompt) 1264 "Interactively choose a template from the list TEMPLATES. 1265 1266TEMPLATES is a list of `yas/template'." 1267 (when templates 1268 (some #'(lambda (fn) 1269 (funcall fn (or prompt "Choose a snippet: ") 1270 templates 1271 #'yas/template-name)) 1272 yas/prompt-functions))) 1273 1274(defun yas/prompt-for-keys (keys &optional prompt) 1275 "Interactively choose a template key from the list KEYS." 1276 (when keys 1277 (some #'(lambda (fn) 1278 (funcall fn (or prompt "Choose a snippet key: ") keys)) 1279 yas/prompt-functions))) 1280 1281(defun yas/prompt-for-table (tables &optional prompt) 1282 (when tables 1283 (some #'(lambda (fn) 1284 (funcall fn (or prompt "Choose a snippet table: ") 1285 tables 1286 #'yas/snippet-table-name)) 1287 yas/prompt-functions))) 1288 1289(defun yas/x-prompt (prompt choices &optional display-fn) 1290 (when (and window-system choices) 1291 (let ((keymap (cons 'keymap 1292 (cons 1293 prompt 1294 (mapcar (lambda (choice) 1295 (list choice 1296 'menu-item 1297 (if display-fn 1298 (funcall display-fn choice) 1299 choice) 1300 t)) 1301 choices))))) 1302 (when (cdr keymap) 1303 (car (x-popup-menu (if (fboundp 'posn-at-point) 1304 (let ((x-y (posn-x-y (posn-at-point (point))))) 1305 (list (list (+ (car x-y) 10) 1306 (+ (cdr x-y) 20)) 1307 (selected-window))) 1308 t) 1309 keymap)))))) 1310 1311(defun yas/ido-prompt (prompt choices &optional display-fn) 1312 (when (and (featurep 'ido) 1313 ido-mode) 1314 (let* ((formatted-choices (or (and display-fn 1315 (mapcar display-fn choices)) 1316 choices)) 1317 (chosen (and formatted-choices 1318 (ido-completing-read prompt 1319 formatted-choices 1320 nil 1321 'require-match 1322 nil 1323 nil)))) 1324 (when chosen 1325 (nth (position chosen formatted-choices :test #'string=) choices))))) 1326 1327(eval-when-compile (require 'dropdown-list nil t)) 1328(defun yas/dropdown-promp…
Large files files are truncated, but you can click here to view the full file