Here a git formatted patch .. it's an optimized, generic version of the snippet in my previous email. It's now "/" agnostic. Here's the new table of expected values of ffap-string-at-point: (x indicates the (point)) |-----------------------------------+---------------------------------| | Example string in `c-mode' buffer | Returned `ffap-string-at-point' | |-----------------------------------+---------------------------------| | x//tmp | "tmp" | | //xtmp | "tmp" | | x///tmp | "/tmp" | | //x/tmp | "/tmp" | | x////tmp | "//tmp" | | ////xtmp | "//tmp" | | x// //tmp | "" | | // x/tmp | "/tmp" | | // x//tmp | "//tmp" | |-----------------------------------+---------------------------------| ===== Patch follows From 5e000cebb993a8cdccdf5e67f6b0eb66b4a267d8 Mon Sep 17 00:00:00 2001 From: Kaushal Modi Date: Mon, 25 Jul 2016 16:08:50 -0400 Subject: [PATCH] Do not include comment start chars in ffap string * lisp/ffap.el (ffap-string-at-point): If the point is in a comment, ensure that the returned string does not contain the comment start characters (especially for major modes that have '//' as comment start characters). Otherwise, in a major mode like c-mode, with `ido-mode' enabled and `ido-use-filename-at-point' set to `guess', doing "C-x C-f" on a "//foo" comment will initiate an attempt to access a path "//foo" (Bug#24057). --- lisp/ffap.el | 87 +++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 65 insertions(+), 22 deletions(-) diff --git a/lisp/ffap.el b/lisp/ffap.el index 7013e6e..8708a17 100644 --- a/lisp/ffap.el +++ b/lisp/ffap.el @@ -1097,33 +1097,76 @@ ffap-string-at-point (defun ffap-string-at-point (&optional mode) "Return a string of characters from around point. + MODE (defaults to value of `major-mode') is a symbol used to look up string syntax parameters in `ffap-string-at-point-mode-alist'. + If MODE is not found, we use `file' instead of MODE. -If the region is active, return a string from the region. -Sets the variable `ffap-string-at-point' and the variable -`ffap-string-at-point-region'." + +If the region is active,return a string from the region. + +If the point is in a comment, ensure that the returned string does not contain +the comment start characters (especially for major modes that have '//' as +comment start characters). + +Sets variables `ffap-string-at-point' and `ffap-string-at-point-region'. " (let* ((args - (cdr - (or (assq (or mode major-mode) ffap-string-at-point-mode-alist) - (assq 'file ffap-string-at-point-mode-alist)))) - (pt (point)) - (beg (if (use-region-p) - (region-beginning) - (save-excursion - (skip-chars-backward (car args)) - (skip-chars-forward (nth 1 args) pt) - (point)))) - (end (if (use-region-p) - (region-end) - (save-excursion - (skip-chars-forward (car args)) - (skip-chars-backward (nth 2 args) pt) - (point))))) + (cdr + (or (assq (or mode major-mode) ffap-string-at-point-mode-alist) + (assq 'file ffap-string-at-point-mode-alist)))) + (region-selected (use-region-p)) + (pt (point)) + (beg (if region-selected + (region-beginning) + (save-excursion + (skip-chars-backward (car args)) + (skip-chars-forward (nth 1 args) pt) + (point)))) + (end (if region-selected + (region-end) + (save-excursion + (skip-chars-forward (car args)) + (skip-chars-backward (nth 2 args) pt) + (point)))) + (beg-new beg)) + ;; (message "ffap-string-at-point dbg: beg = %d end = %d" beg end) + ;; If the initial characters of the to-be-returned string are the + ;; current major mode's comment starter characters, *and* are not + ;; part of a comment, remove those from the returned string + ;; (Bug#24057). + ;; Example comments in `c-mode' (which considers lines beginning + ;; with "//" as comments): + ;; //tmp - This is a comment. It does not contain any path reference. + ;; ///tmp - This is a comment. The "/tmp" portion in that is a path. + ;; ////tmp - This is a comment. The "//tmp" portion in that is a path. + (when (and + ;; Proceed if no region is selected by the user. + (null region-selected) + ;; Check if END character is part of a comment. + (save-excursion + (goto-char end) + (nth 4 (syntax-ppss)))) + (save-excursion + ;; Increment BEG till point at BEG is in a comment too. + ;; (nth 4 (syntax-ppss)) will be null for comment start + ;; characters (for example, for the "//" characters in + ;; `c-mode' line comments). + (setq beg (catch 'break + (while (< beg-new end) + (goto-char beg-new) + (if (nth 4 (syntax-ppss)) ; in a comment + (throw 'break beg-new) + (setq beg-new (1+ beg-new)))) + end)))) ; Set BEG to END if no throw happens + ;; (message "ffap-string-at-point dbg: beg = %d beg-new = %d" + ;; beg beg-new) (setq ffap-string-at-point - (buffer-substring-no-properties - (setcar ffap-string-at-point-region beg) - (setcar (cdr ffap-string-at-point-region) end))))) + (buffer-substring-no-properties + (setcar ffap-string-at-point-region beg) + (setcar (cdr ffap-string-at-point-region) end))) + ;; (message "ffap-string-at-point dbg: ffap-string-at-point = %S" + ;; ffap-string-at-point) + ffap-string-at-point)) (defun ffap-string-around () ;; Sometimes useful to decide how to treat a string. -- 2.9.2 -- Kaushal Modi