emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: An easier way to edit variables


From: João Távora
Subject: Re: An easier way to edit variables
Date: Wed, 14 Jan 2015 15:20:51 +0000
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.4 (windows-nt)

Tom <address@hidden> writes:

> Tom <adatgyujto <at> gmail.com> writes:
>> 
>> I think it was pressing e for edit in the Help buffer, then
>> the buffer is narrowed to the variable value only (which can be a 
>> complex list or anything) which you can modify in place and
>> then press C-c C-c to apply it to the variable and exit
>> edit mode.
>> 
>
> BTW, I should add that when I wrote "easier" in the subject I 
> meant easier for Lisp hackers who change Lisp variables on
> a daily basis.
>
> That's why a quick edit feature in the Help buffer is useful, because
> you already see the value there, so if it's complex list
> (e.g. a font lock setting or anything) then you don't have to
> copy it etc, if you just want to change one thing in it,
> you just press e, you get the lisp value, you edit it,
> press C-c C-c and it is applied instantly.

I still find this idea very good. Some time ago, I presented a quick
hack for this in

   https://lists.gnu.org/archive/html/emacs-devel/2014-01/msg01053.html

You made some comments, but the discussion died or something.

Here's a not-so-quick hack that addresses those concerns. It emulates
widgets in the *Help* buffer and you edit the variable's value in
place. Should support buffer-local vars but I didn't test much. Also no
"eval" is used, the form is just read back much like it was printed.

It's still a bit broken in, bringing the field to 0-length breaks
it. Should use an overlay. And maybe use "proper" widgets? Probably
broken in more ways I didn't see.

Still, can anyone test it and give me some feedback? The diff is against
emacs-24.4 sorry, I'm on windows and no git clone. 

João

*** z:/Vendor/emacs-w64-24.4/share/emacs/24.4/lisp/help-fns.el.gz
--- z:/Vendor/emacs-24.4/share/emacs/24.4/lisp/help-fns.el
***************
*** 610,615 ****
--- 610,686 ----
                            version package))))))
      output))
  
+ (defun help--editable-find-near-point (&optional pos)
+   (let* ((pos (or pos (point)))
+          (field-pos
+           (if (eq 'help--editable-field (car (field-at-pos pos)))
+               pos
+             (let ((p (point-min)))
+               (while (and (setq p (next-single-property-change p 'field))
+                           (not (eq 'help--editable-field (car (field-at-pos 
p))))))
+               p))))
+     (or field-pos
+         (error "No editable field found"))))
+ 
+ (defun help-edit-editable-field (field-pos)
+   (interactive (list (help--editable-find-near-point)))
+   (read-only-mode -1)
+   (let ((start (field-beginning field-pos))
+         (end (field-end field-pos)))
+     (add-text-properties
+      (point-min) start
+      '(rear-nonsticky (read-only) read-only t))
+     (put-text-property end (point-max) 'read-only t)
+     (add-text-properties
+      start end
+      `(local-map ,help--editing-field-keymap
+                  face widget-field
+                  font-lock-face 'widget-field
+                  front-sticky (face font-lock-face field local-map)))))
+ 
+ (defun help-commit-editable-field (field-pos)
+   (interactive (list (help--editable-find-near-point)))
+   (let* ((field (field-at-pos field-pos))
+          (string (field-string-no-properties field-pos))
+          (read (car (read-from-string string)))
+          (variable (cdr (assoc 'variable (cdr field))))
+          (locus (cdr (assoc 'locus (cdr field)))))
+     (cond ((bufferp locus)
+            (with-current-buffer locus
+              (set (make-local-variable variable) read)))
+           (t
+            (set-default variable read)))
+     (help-quit-editable-field field-pos)))
+ 
+ (defun help-quit-editable-field (_field-pose)
+   (interactive (help--editable-field-interactive))
+   ;; TODO: a better implementation might be to restore the text
+   ;; properties and the text according to the
+   ;; `original-representation' prop. But this is safer for now.
+   (revert-buffer nil t))
+ 
+ (defvar help--editable-field-keymap
+   (let ((map (make-sparse-keymap)))
+     (define-key map (kbd "v") 'help-edit-editable-field)
+     map))
+ 
+ (defvar help--editing-field-keymap
+   (let ((map (make-sparse-keymap)))
+     (define-key map (kbd "C-c C-c") 'help-commit-editable-field)
+     (define-key map (kbd "C-c C-q") 'help-quit-editable-field)
+     map))
+ 
+ (defun help--insert-editable-field (variable
+                                     representation
+                                     &optional locus)
+   (insert (propertize
+            representation
+            'field `(help--editable-field
+                     . ((original-representation . ,representation)
+                        (variable                . ,variable)
+                        (locus                   . ,locus)))
+            'keymap help--editable-field-keymap)))
+ 
  ;;;###autoload
  (defun describe-variable (variable &optional buffer frame)
    "Display the full documentation of VARIABLE (a symbol).
***************
*** 684,692 ****
                       (let ((print-quoted t))
                         (prin1-to-string val))))
                  (if (< (+ (length print-rep) (point) (- line-beg)) 68)
!                     (insert print-rep)
                    (terpri)
!                   (pp val)
                    (if (< (point) (+ 68 (line-beginning-position 0)))
                        (delete-region from (1+ from))
                      (delete-region (1- from) from)))
--- 755,765 ----
                       (let ((print-quoted t))
                         (prin1-to-string val))))
                  (if (< (+ (length print-rep) (point) (- line-beg)) 68)
!                       (help--insert-editable-field variable
!                                                    print-rep
!                                                    locus)
                    (terpri)
!                   (help--insert-editable-field variable (pp-to-string val) 
locus)
                    (if (< (point) (+ 68 (line-beginning-position 0)))
                        (delete-region from (1+ from))
                      (delete-region (1- from) from)))
***************
*** 728,734 ****
                      ;; probably print it raw once and check it's a
                      ;; sensible size before prettyprinting.  -- fx
                      (let ((from (point)))
!                       (pp global-val)
                        ;; See previous comment for this function.
                        ;; (help-xref-on-pp from (point))
                        (if (< (point) (+ from 20))
--- 801,807 ----
                      ;; probably print it raw once and check it's a
                      ;; sensible size before prettyprinting.  -- fx
                      (let ((from (point)))
!                         (help--insert-editable-field variable (pp-to-string 
global-val))
                        ;; See previous comment for this function.
                        ;; (help-xref-on-pp from (point))
                        (if (< (point) (+ from 20))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]