3

In conjunction with a user-configuration of (delete-selection-mode 1), is there a way to consolidate the two following Yasnippets into just one snippet so that it will work differently depending upon whether the region is active. For example: (if (region-active-p) (yas/selected-text) "$1")

Active region -- surround the active region with the snippet:

# -*- mode: snippet -*-
# contributor: lawlist
# key: bold_selected
# name: bold_selected
# binding: C-I b b s
# --
{\bf `yas/selected-text`}

Non-active region -- insert the snippet and place the cursor at the position of $1:

# -*- mode: snippet -*-
# contributor: lawlist
# key: bold
# name: bold
# binding: C-I b b b
# --
{\bf $1}
lawlist
  • 13,099
  • 3
  • 49
  • 158

3 Answers3

4

Back-ticks surrounding the elisp code to be evaluated are required. The built-in variable yas-selected-text stores the text of the selected region, which can be used to reinsert the same text during the snippet creation. Four (4) backslashes are needed for every one (1) backslash.

# -*- mode: snippet -*-
# contributor: lawlist
# key: bold
# name: bold
# binding: TAB <f6>
# --
`(if (region-active-p)
   (concat
     "{\\\\bf "
     yas-selected-text
     "}")
   "{\\\\bf $1}")`
lawlist
  • 13,099
  • 3
  • 49
  • 158
  • @PaulPichaureau -- I've been using this solution for 2 years without any problems. Please provide some details regarding what else you have tried and what solution (if any) you have found. People reading this thread have no idea whether you have any Emacs experience, including, but not limited to experience configuring and using the `yasnippet` library. To post a comment that it does not work and downvote without any further explanation does others a disservice. For all we know, you may have something wrong with your setup that prevents this answer from working properly. – lawlist Feb 17 '17 at 16:27
  • I've tested this snippet on MacOS, emacs 25.1, last version of yasnippet, and an init file with only three lines : (require 'package) (package-initialize) (yas-global-mode 1). It doesn't work. Perhaps you have something special on your config that make this snippet work. Can you provide some details? – Paul Pichaureau Apr 04 '17 at 16:19
  • @PaulPichaureau -- In an older version of `yasnippet`, pressing the `tab` followed by `f6` calls the command `yas-expand-from-keymap`. I downloaded the latest version of `yasnippet` today -- `tab`+`f6` calls `yas-expand` (bound in the `yas-minor-mode-map`). My older version of `yasnippet` doesn't even have that variable. To test out this snippet, please highlight/select the text that you wish to surround and then use the drop-down menu in the menu-bar to select this `bold` snippet, and it will correctly surround the text. It may be necessary to debug the fallback behavior for `yas-expand`. – lawlist Apr 04 '17 at 17:55
3
# -*- mode: snippet -*-
# name: bold
# key: bold
# type: command
# --
(if (region-active-p)
    (yas-expand-snippet "{\\bf `yas-selected-text`}")
  (yas-expand-snippet "{\\bf $0}"))
jpkotta
  • 9,237
  • 3
  • 29
  • 34
  • Thank you for taking a first stab at the solution. When using the most recent version of Yasnippet (0.8.0) with Emacs Trunk built on March 19, 2014, the selected region gets deleted rather than surrounded by the snippet. Tested with a virtually empty `.emacs` file and only the installation of Yasnippet -- i.e., `.emacs` file contains: `(require 'package) (package-initialize) (require 'yasnippet) (yas-global-mode 1)` – lawlist Apr 01 '14 at 16:33
  • The snippet works OK for me, so there's some environment that makes it work. I have `delete-selection-mode` disabled, but I do have `cua-selection-mode` enabled, so my selections get deleted when I type text anyway. Maybe try putting a `(let (delete-selection-mode) ...)` around the `if`. – jpkotta Apr 01 '14 at 18:55
  • Also, I'm using yasnippet 20140314 from melpa, and Emacs 24.3.1. – jpkotta Apr 01 '14 at 18:58
  • Perhaps there is another variable in Yasnippet that needs to be set (e.g., `yas-wrap-around-region`) in order for your solution to work. I'll open up the source code in the next few days and see if I can track it down. – lawlist Apr 01 '14 at 20:04
  • FWIW, I have no yasnippet customizations. I just reorder `yas-prompt-functions` and enable `yas-global-mode`. – jpkotta Apr 02 '14 at 17:14
2

I am using this snippet to conditionally wrap variables in JavaScript template literals.

If there is selected text, then $1 uses that. Otherwise it uses the default value var which the user can overtype to replace the mirrored instance of $1.

# -*- coding: utf-8; mode: snippet -*-
# name: wrap variable in string template to log its value `var=${var}`
# expand-env : ((yas-wrap-around-region nil))
# --
${1:`(if (region-active-p) (yas-selected-text) "var")`}=\${$1}$0

For your problem, this snippet seems to work

# -*- coding: utf-8; mode: snippet -*-
# name: wrap selected text, or user provided text, in bold font
# expand-env: ((yas-wrap-around-region nil))
# --
{\bf ${1:`(if (region-active-p) (yas-selected-text) "text-to-bold")`}}$0
Bae
  • 7,516
  • 5
  • 36
  • 42