-4

The following function replaces character sequences for the cases of prefixes and suffixes. I would also like to handle the case of matches that occur medially within a word (e.g. insert p' for occurrence of ple'), meaning that the word contains at least a single character on either side of the character sequence `ple'.

Would like to use

    (defun shorten-word ()
      "Shortens a word according to specific rules."
    
      (interactive)
    
      (let* ((bounds (bounds-of-thing-at-point 'word))
         (s (car bounds))
         (case-fold-search nil)
         (e (make-marker))
         (p (point-marker)))
    
        (when s
          (set-marker e (cdr bounds))
          (goto-char s)
          (cond

             ((search-forward-regexp
                 (concat  "\\<"
                 (regexp-opt '("cog" "col" "com" "con" "cor" "cum" "coun")))
                 (cdr bounds)
                 t)
    
            (replace-match "k"))
      
           ;;-----------------------------------------------
           ;; Insert `l' for words with final
           ;; `ley', `ily', and `ly'.  
           ((search-forward-regexp
            (concat (regexp-opt '("ley" "ily" "ly")) "\\>")
               (cdr bounds))
    
            (replace-match "l"))
        
           ;;-----------------------------------------------
           ;; Insert letter `p' for median `ple'.

            ((save-excursion
                (re-search-forward "ple" e t))
                (replace-match "p"))
           
           ;;-----------------------------------------------
           (t nil))
    
          (goto-char p))
        (set-marker e nil)
        (set-marker p nil)))
10
  • At least two issues: (1) this errors if there are no matches for the "ily" things---add an argument t at the end of the search-forward-regexp form. (2) this send "please" to "pase" because you have not checked for mid-word in the final search. Aug 17 at 9:03
  • What can be a solution to a mid-word search?
    – Ephram
    Aug 17 at 10:07
  • I could move forward one char, to make sure I don't match anything at the beginning of the word.
    – Ephram
    Aug 17 at 10:13
  • 1
    You already have a solution for the mid-word issue: emacs.stackexchange.com/questions/73073/… Aug 17 at 10:42
  • 1
    Implementation: all the methods you have rely on a regex and that is independent of the implementation. Aug 17 at 14:43

1 Answer 1

0

A quick answer is impossible (any answer is impossible). Here's a small change to the above that does approximately what you want:

...
(cond

             ((search-forward-regexp
                 (concat  "\\<"
                 (regexp-opt '("cog" "col" "com" "con" "cor" "cum" "coun")))
                 (cdr bounds)
                 t)
    
            (replace-match "k"))
      
           ;;-----------------------------------------------
           ;; Insert `l' for words with final
           ;; `ley', `ily', and `ly'.  
           ((search-forward-regexp
            (concat (regexp-opt '("ley" "ily" "ly")) "\\>")
               (cdr bounds) t)
    
            (replace-match "l"))
        
           ;;-----------------------------------------------
           ;; Insert letter `p' for median `ple'.
           ((search-forward-regexp "\\w\\(ple\\)\\w" (cdr bounds) t)
            (replace-match "p" nil nil nil 1))

 
           ;;-----------------------------------------------
           (t nil))
    
...

The regexp "\\w\\(ple\\)\\w" uses grouping to remember that ple was the match of the first (and only) parenthesized subexpression and that fact is used in (replace-match "p" nil nil nil 1) to replace only that part (the final 1 says so) with p. Do C-h f replace-match for the details.

But your problem is woefully underspecified. What do you want to happen on completely? Should it become kpletely, completel, kpletl, comptely, comptel, kptely or kptel? The function does the first one, but it's not clear what you want it to do. Since we don't know where you are trying to go, all we can do is fix the most egregious problems and hope that it might somehow help.

Our quandary is: Do we answer a seemingly endless stream of questions, some of which may be related but all slightly different (like the twisty little passages of the old "Adventure" game), about all sorts of problems that may or not be relevant to anything? Do we just ignore you and hope you go away? Or do we do something in-between to try to help you to understand why your questions are impossible to answer? I think most of us have gone some way in the third direction: I think I've tried to do that to the extent possible, but the problem is that I'm not seeing much progress and I cannot hold much hope that your questions will become better in the future. I'm certainly not willing on a regular basis to expend as much time as I have expended on this answer alone, let alone on multiple questions every day.

I am sorry to have to say this, but unless I see serious improvement, I don't think I'll be answering any questions of yours in the future. I have too many other things to do and not enough time to do them, so I have to prioritize where my time is spent - as do we all.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.