8

I was looking at this on StackOverflow and was wondering if there was a nice way built-in to edit strings of text stored in variables as if they were buffers? M-x set-variable doesn't really cut it when you have a long string of LaTeX options inside a variable.

I'm looking for behavior similar to the package string-edit, but in order to edit emacs variables.

wdkrnls
  • 3,657
  • 2
  • 27
  • 46
  • I'm envisioning something along the lines of string-edit but which recognizes variables. – wdkrnls Dec 01 '14 at 17:53
  • What do you mean by "recognizes variables"? – Malabarba Dec 02 '14 at 02:05
  • 1
    If you download string-edit from melpa, you'll see how that lets you edit a string as if it were in its own separate buffer. I'd like to (edit-variable-at-point) and have it bring up a buffer containing a representation of the contents of the variable, especially if that variable is a string. – wdkrnls Dec 02 '14 at 02:36

3 Answers3

4

If they are user options, then M-x customize-option.

If they are defvars, not options, then edit the value in the source buffer or in a copy of the defvar in another buffer.

Or use M-: (setq THE-VAR "edit the text in the minibuffer).

Drew
  • 75,699
  • 9
  • 109
  • 225
4

Combining string-edit with a bit of custom elisp can provide the feature you want. For example, the function below will enable you to edit the value of a variable in string-edit-mode, provided that this variable is string-valued.

(defun my/edit-string-variable-at-point ()
  "If the symbol at point is a string-valued variable, update it
using `string-edit' to provide the new value."
  (interactive)
  (let ((variable (intern (thing-at-point 'symbol t))))
    (with-current-buffer (get-buffer-create "*edit-variable*")
      (erase-buffer)
      (print `(setq ,variable ,(symbol-value variable))
             (current-buffer))
      (goto-char (- (point-max) 3))
      (if (string-edit-at-point)
          ;; Variable value is a string
          ;; Overrides C-c C-c so that the new value is evaluated after `string-edit-conclude'
          (let ((oldmap (cdr (assoc 'string-edit-mode minor-mode-map-alist)))
                (newmap (make-sparse-keymap)))
            (set-keymap-parent newmap oldmap)
            (define-key newmap (kbd "C-c C-c")
              #'(lambda ()
                  (interactive)
                  (string-edit-conclude)
                  (eval-buffer)
                  (kill-buffer)))
            (make-local-variable 'minor-mode-overriding-map-alist)
            (push `(string-edit-mode . ,newmap) minor-mode-overriding-map-alist))
        ;; Variable value was not a string
        (message "`%s' is not a string!" variable)
        (kill-buffer)))))
François Févotte
  • 5,917
  • 1
  • 24
  • 37
1

Go to the *scratch* buffer and create a template (setq var-name '...). Now type C-h v var-name. Use M-w to copy the value, then yank it into the *scratch* buffer, replacing the .... Edit to your heart's content, then go to the end of the buffer and C-x C-e (eval-last-sexp).

I'm not actually familiar with string-edit, so this may not be what you hoped for. I just needed to edit a large variable and wanted to do it without having to futz around with installing packages. This works.

Norman Ramsey
  • 1,113
  • 6
  • 13