[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Function to replace spaces with underscores
From: |
Pascal J. Bourguignon |
Subject: |
Re: Function to replace spaces with underscores |
Date: |
Tue, 17 Sep 2013 20:04:43 +0200 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/24.2 (gnu/linux) |
pico77 <grammophonia@gmail.com> writes:
> Dear all,
>
>
> at the end of this post there is a function that I load in my .emacs file.
> The main goal is to take a selected line and remove all spaces with
> underscore. This is very useful to produce file-names from copy/past
> consistently without spaces. But there is a problem with that.
>
>
> If I open emacs select a line ad do M-x s2u then it works fine, but if I do
> it further it requires to apply the function 3 times before to get it done.
> So the problem is really that probably the function is programmed in a way
> that after the first applucation of s2u there is something which has to be
> cleaned up before to re-apply the same function.
>
> I am not a lisp/emacs expert and the function was passed by a friend who is
> now not able to solve the problem. I hope somebody out there can help to
> find the bug!
Indeed, as Eli said, the specifications of this command are strange, and
rather impractical. What if you make a different selection? You won't
be able to easily replace spaces to underscore on two different regions.
It would be better either to
1- select the target separator from a prefix argument.
Eg. C-u M-x s2u RET would use ?_ instead of ?- and
C-- M-x s2u RET would use ? instead of ?-, or
(defun s2u (replacement start end)
(interactive "*P\nr")
(save-excursion
(let ((repchar (cond
((null replacement) "-")
((consp replacement) "_")
((eq '- replacement) " ")
((minusp replacement) " ")
((zerop replacement) "-")
(t "_"))))
(goto-char start)
(while (re-search-forward "[- _]" end t)
(delete-region (match-beginning 0) (match-end 0))
(insert repchar)))))
2- look at what separator is used in the region and select the next one
from there. The difficulty here being that there are several states:
- the region contains various separators -> ?-
- the region contains no separator -> no change
- the region contains ? but no ?- or ?_ -> ?-
- the region contains ?- but no ? or ?_ -> ?_
- the region contains ?_ but no ?- or ? -> ?
I'd propose the indicated transitions.
(defun collect-substrings (regexp start end)
(let ((results '()))
(goto-char start)
(while (re-search-forward regexp end t)
(push (buffer-substring (match-beginning 0) (match-end 0)) results))
(nreverse results)))
(defun* s2u (start end)
(interactive "*r")
(save-excursion
(let* ((separators (remove-duplicates (collect-substrings "[- _]" start
end)
:test (function string=)))
(repchar (cond
((null separators) (return-from s2u))
((rest separators) "-")
((string= (first separators) " ") "-")
((string= (first separators) "-") "_")
((string= (first separators) "_") " "))))
(goto-char start)
(while (re-search-forward "[- _]" end t)
(delete-region (match-beginning 0) (match-end 0))
(insert repchar)))))
--
__Pascal Bourguignon__
http://www.informatimago.com/