[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))
- An easier way to edit variables, Tom, 2015/01/13
- Re: An easier way to edit variables, Tom, 2015/01/14
- Re: An easier way to edit variables, Yuri Khan, 2015/01/14
- Re: An easier way to edit variables, Tom, 2015/01/14
- Re: An easier way to edit variables, Ted Zlatanov, 2015/01/14