[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH] w3m-lnum add highlight
- From: Andrey Kotlarski <m00naticus@xxxxxxxxx>
- Date: Tue, 06 Jul 2010 01:31:49 +0300
- X-ml-name: emacs-w3m
- X-mail-count: 11253
- References: <87630wfds0.fsf@xxxxxxxxx> <b4m1vbij0vi.fsf@xxxxxxx>
Hello, Katsumi-san,
thanks for feedback and sorry for slight delay. I decided to go a step
further in emulating Conkeror's behavior. There's a function
`w3m-linknum-follow' which follows urls, activates form fields or pushes
buttons depending on what's selected (not sure whether done correctly
but works where tested). It might be heretic but I changed behavior
(along highlighting matches) of `w3m-go-to-linknum' allowing it to go to
form fields and buttons as well, which seems more natural to me as
these elements are normally more difficult to "isearch". Added a macro
`w3m-with-linknum' which can ease this type of functions (and bring old
behavior of `w3m-go-to-linknum' with a single digit change). Made
`w3m-link-numbering-mode' more flexible allowing it 2 types of
enumeration - only url links (old behaviour and default) and urls along
with form fields and buttons for conveniences pointed above. Also added
`w3m-linknum-read-url' for comfortable grabbing of urls and allowing for
such sort of actions:
(let ((url (w3m-linknum-read-url "Curl on link: ")))
(if url (async-shell-command (concat "curl -O " url))))
A glitch that haven't yet overcome is changing faces of buttons on match.
Here's the diff against same current cvs w3m-lnum.el and hopefully this
time will work closer to advertised.
--- /home/andrey2/.emacs.d/extras/w3m/w3m-lnum-cvs.el 2010-04-27 15:46:24.000000000 +0300
+++ /home/andrey2/.emacs.d/extras/w3m/w3m-lnum.el 2010-07-06 01:27:28.681678592 +0300
@@ -1,6 +1,6 @@
;;; w3m-lnum.el --- Operations using link numbers
-;; Copyright (C) 2004, 2005, 2006, 2007, 2009
+;; Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010
;; TSUCHIYA Masatoshi <tsuchiya@xxxxxxxxxx>
;; Authors: TSUCHIYA Masatoshi <tsuchiya@xxxxxxxxxx>
@@ -34,6 +34,7 @@
;; expressions to your ~/.emacs-w3m.
;; (autoload 'w3m-link-numbering-mode "w3m-lnum" nil t)
+;; (autoload 'w3m-linknum-follow "w3m-lnum" nil t)
;; (add-hook 'w3m-mode-hook 'w3m-link-numbering-mode)
;;; Code:
@@ -67,57 +68,80 @@
(defvar w3m-link-numbering-mode nil
"Non-nil if w3m operations using link numbers are enabled.")
(make-variable-buffer-local 'w3m-link-numbering-mode)
-(unless (assq 'w3m-link-numbering-mode minor-mode-map-alist)
- (push (cons 'w3m-link-numbering-mode w3m-link-numbering-mode-map)
- minor-mode-map-alist))
+(or (assq 'w3m-link-numbering-mode minor-mode-map-alist)
+ (push (cons 'w3m-link-numbering-mode w3m-link-numbering-mode-map)
+ minor-mode-map-alist))
+
+(defun w3m-linknum-remove-overlays (&optional arg)
+ "Remove numbering and match overlays.
+With ARG remove only temporary match"
+ (if arg
+ (dolist (overlay (overlays-in (point-min) (point-max)))
+ (if (overlay-get overlay 'w3m-linknum-match)
+ (delete-overlay overlay)))
+ (dolist (overlay (overlays-in (point-min) (point-max)))
+ (if (or (overlay-get overlay 'w3m-link-numbering-overlay)
+ (overlay-get overlay 'w3m-linknum-match))
+ (delete-overlay overlay)))))
;;;###autoload
(defun w3m-link-numbering-mode (&optional arg)
- "Minor mode to enable operations using link numbers."
+ "Minor mode to enable operations using link numbers.
+With prefix ARG 0 disable mode, with prefix 4 index forms as well."
(interactive "P")
(add-hook 'w3m-display-functions 'w3m-link-numbering)
- (if (setq w3m-link-numbering-mode
- (if arg
- (> (prefix-numeric-value arg) 0)
- (not w3m-link-numbering-mode)))
- (progn
- (w3m-link-numbering)
- (run-hooks 'w3m-link-numbering-mode-hook))
- (dolist (overlay (overlays-in (point-min) (point-max)))
- (when (overlay-get overlay 'w3m-link-numbering-overlay)
- (delete-overlay overlay)))))
+ (let (diff)
+ (setq w3m-link-numbering-mode
+ (if arg
+ (let ((arg (prefix-numeric-value arg)))
+ (when (not (= arg 0))
+ (setq diff (not (eq arg w3m-link-numbering-mode)))
+ arg))
+ (if (not w3m-link-numbering-mode) 1)))
+ (if w3m-link-numbering-mode
+ (progn
+ (if diff (w3m-linknum-remove-overlays))
+ (if (= w3m-link-numbering-mode 4)
+ (w3m-link-numbering t)
+ (w3m-link-numbering))
+ (run-hooks 'w3m-link-numbering-mode-hook))
+ (w3m-linknum-remove-overlays))))
(defun w3m-link-numbering (&rest args)
- "Make overlays that display link numbers."
- (when w3m-link-numbering-mode
- (save-excursion
- (goto-char (point-min))
- (let ((i 0)
- overlay num)
- (catch 'already-numbered
- (while (w3m-goto-next-anchor)
- (when (w3m-anchor)
- (when (get-char-property (point) 'w3m-link-numbering-overlay)
- (throw 'already-numbered nil))
- (setq overlay (make-overlay (point) (1+ (point)))
- num (format "[%d]" (incf i)))
- (w3m-static-if (featurep 'xemacs)
- (progn
+ "Make overlays that display link numbers.
+With prefix ARGS index forms as well."
+ (if w3m-link-numbering-mode
+ (save-excursion
+ (goto-char (point-min))
+ (let ((i 0)
+ overlay num)
+ (catch 'already-numbered
+ (while (w3m-goto-next-anchor)
+ (let ((p (point)))
+ (when (or args (get-char-property p 'w3m-href-anchor))
+ (if (get-char-property p
+ 'w3m-link-numbering-overlay)
+ (throw 'already-numbered nil))
+ (setq overlay (make-overlay p (1+ p))
+ num (format "[%d]" (incf i)))
+ (w3m-static-if (featurep 'xemacs)
+ (progn
+ (overlay-put overlay 'before-string num)
+ (set-glyph-face (extent-begin-glyph overlay)
+ 'w3m-link-numbering))
+ (w3m-add-face-property 0 (length num)
+ 'w3m-link-numbering num)
(overlay-put overlay 'before-string num)
- (set-glyph-face (extent-begin-glyph overlay)
- 'w3m-link-numbering))
- (w3m-add-face-property 0 (length num) 'w3m-link-numbering num)
- (overlay-put overlay 'before-string num)
- (overlay-put overlay 'evaporate t))
- (overlay-put overlay 'w3m-link-numbering-overlay i))))))))
+ (overlay-put overlay 'evaporate t))
+ (overlay-put overlay
+ 'w3m-link-numbering-overlay i)))))))))
(defun w3m-move-numbered-anchor (&optional arg)
"Move the point to the specified anchor.
When no prefix argument is specified, call `w3m-view-this-url' instead
of moving cursor."
(interactive "P")
- (if (and arg
- (> (setq arg (prefix-numeric-value arg)) 0))
+ (if (and arg (> (setq arg (prefix-numeric-value arg)) 0))
(catch 'found
(dolist (overlay (overlays-in (point-min) (point-max)))
(when (eq arg (overlay-get overlay 'w3m-link-numbering-overlay))
@@ -125,19 +149,156 @@
(push (w3m-anchor-sequence) w3m-goto-anchor-hist)
(w3m-horizontal-on-screen)
(throw 'found (w3m-print-this-url))))
- (error "Cannot found your specified link: %d" arg))
+ (error "Cannot find specified link: %d" arg))
(w3m-view-this-url)))
-(defun w3m-go-to-linknum ()
- "Turn on link numbers and ask for one to go to."
- (interactive)
- (let ((active w3m-link-numbering-mode))
- (unless active
- (w3m-link-numbering-mode 1))
- (unwind-protect
- (w3m-move-numbered-anchor (w3m-read-number "Anchor number: "))
- (unless active
- (w3m-link-numbering-mode 0)))))
+(defun w3m-read-int-interactive (prompt fun &optional default)
+ "Interactively read a valid integer from minubuffer with PROMPT.
+Execute a one argument function FUN with every current valid integer.
+Initial value is DEFAULT if specified or 0.
+Use <return> to submit current value and <backspace> for correction."
+ (let ((prompt (propertize prompt 'face 'minibuffer-prompt))
+ (num (or default 0))
+ (min-len (length prompt))
+ ch)
+ (let ((temp-prompt (format "%s%d" prompt num)))
+ (while (not (eq (setq ch (read-event temp-prompt)) 'return))
+ (cond ((and (eq ch 'backspace)
+ (> (length temp-prompt) min-len))
+ (setq num (/ num 10)
+ temp-prompt (format "%s%d" prompt num))
+ (funcall fun num))
+ ((and (numberp ch) (> ch 47) (< ch 58))
+ (setq num (+ (* num 10) (- ch 48))
+ temp-prompt (format "%s%d" prompt num))
+ (funcall fun num))))
+ num)))
+
+(defmacro w3m-with-linknum (type &rest body)
+ "Within TYPE anchor numbering execute BODY.
+Then restore previous numbering condition."
+ `(let ((ty ,type)
+ (active (or w3m-link-numbering-mode 0)))
+ (let ((diff (not (= active ty))))
+ (when diff
+ (or (= ty 0) (w3m-link-numbering-mode 0))
+ (w3m-link-numbering-mode ty))
+ (unwind-protect
+ (progn,@body)
+ (if diff
+ (progn
+ (or (= active 0) (w3m-link-numbering-mode 0))
+ (w3m-link-numbering-mode active))
+ (w3m-linknum-remove-overlays t))))))
+
+(defun w3m-highlight-numbered-anchor (arg)
+ "Highlight specified by ARG number anchor."
+ (catch 'done
+ (let (found-prev marked-new)
+ (dolist (overlay (overlays-in (point-min) (point-max)))
+ (cond
+ ((and found-prev marked-new)
+ (throw 'done nil))
+ ((overlay-get overlay 'w3m-linknum-match)
+ (delete-overlay overlay)
+ (setq found-prev t))
+ ((eq arg (overlay-get overlay 'w3m-link-numbering-overlay))
+ (let* ((start (overlay-start overlay))
+ (end (1+ start)))
+ (let ((prop 'w3m-href-anchor)
+ (anchor (get-text-property start 'w3m-href-anchor))
+ (comparator 'equal))
+ (or anchor
+ (setq prop 'w3m-action
+ anchor (get-text-property start 'w3m-action)
+ comparator 'eq))
+ (while (funcall comparator anchor
+ (get-text-property end prop))
+ (setq end (1+ end))))
+ (let ((match-overlay (make-overlay start end)))
+ (overlay-put match-overlay 'w3m-linknum-match t)
+ (overlay-put match-overlay 'face 'match)))
+ (setq marked-new t)))))))
+
+(defun w3m-get-numbered-url (&optional num)
+ "Get url of anchor numbered as NUM.
+If NUM is not specified, find currently highlighted anchor."
+ (catch 'found
+ (if num
+ (dolist (overlay (overlays-in (point-min) (point-max)))
+ (if (eq num (overlay-get overlay
+ 'w3m-link-numbering-overlay))
+ (let ((result (get-text-property (overlay-start overlay)
+ 'w3m-href-anchor)))
+ (throw
+ 'found
+ (let ((pos (overlay-start overlay)))
+ (cons (or result
+ (get-text-property pos 'w3m-action))
+ pos))))))
+ (dolist (overlay (overlays-in (point-min) (point-max)))
+ (if (overlay-get overlay 'w3m-linknum-match)
+ (let ((result (get-text-property (overlay-start overlay)
+ 'w3m-href-anchor)))
+ (throw
+ 'found
+ (let ((pos (overlay-start overlay)))
+ (cons (or result
+ (get-text-property pos 'w3m-action))
+ pos)))))))))
+
+;;;###autoload
+(defun w3m-go-to-linknum (arg)
+ "Turn on link and form numbers and ask for one to go to.
+With prefix ARG don't highlight current link."
+ (interactive "P")
+ (w3m-with-linknum
+ 4 (w3m-move-numbered-anchor
+ (if arg (w3m-read-number "Anchor number: ")
+ (w3m-read-int-interactive "Anchor number: "
+ 'w3m-highlight-numbered-anchor)))))
+
+(defun w3m-linknum-get-action (&optional prompt)
+ "Turn on link numbers and return cons of url or action and position
+of PROMPT selected anchor.
+Highlight every intermediate result anchor."
+ (w3m-with-linknum
+ 4 (w3m-read-int-interactive (or prompt "Anchor number: ")
+ 'w3m-highlight-numbered-anchor)
+ (w3m-get-numbered-url)))
+
+;;;###autoload
+(defun w3m-linknum-follow (arg)
+ "Turn on link numbers, ask for one and execute appropriate action on it.
+When link - visit it, when button - press, when input - activate it.
+With prefix ARG visit link in new session."
+ (interactive "P")
+ (let ((link (w3m-linknum-get-action
+ (concat "Follow " (if arg "in new window ")
+ "(select link): "))))
+ (if (consp link)
+ (cond ((stringp (car link))
+ (if arg (w3m-goto-url-new-session (car link))
+ (goto-char (cdr link))
+ (w3m-goto-url (car link))))
+ ((eq (caar link) 'w3m-form-submit)
+ (widget-button-press (cdr link) (car link)))
+ (t (goto-char (cdr link))
+ (let ((w3m-form-new-session arg)
+ (w3m-form-download nil))
+ (eval (car link)))))
+ (error "No valid link selected"))))
+
+;;;###autoload
+(defun w3m-linknum-read-url (&optional prompt)
+ "Turn on link numbers and return PROMPT selected url.
+Highlight each intermediate result anchor."
+ (w3m-with-linknum
+ 1 (w3m-read-int-interactive (or prompt "Anchor number: ")
+ 'w3m-highlight-numbered-anchor)
+ (let ((link (w3m-get-numbered-url)))
+ (and (consp link) (stringp (car link))
+ (car link)))))
(provide 'w3m-lnum)