Concat string with a specific operator - eclipse

I am using Emacs, Notepad++ or Eclipse. Is there a way to cut a String in small pieces and concat them using a separator?
For instance:
Input:
"I like sushi and maki"
Output:
"I like" +
"sushi and" +
"maki"

In Eclipse (at least in the Java context) you only need to place the cursor inside the string and hit enter. This works also in Netbeans.

In Notepad++ you can use RegEx: ([\w]+)\s*([\w]*) and then replace with "$1 $2" + but then you will have to go back and remove the extraneous + signs from the end replacements that just have one group match.

Below is my take at the problem. Not sure if I'm solving the right problem though :)
(defun split-string-words (min max)
(interactive "r")
(let ((counted 0) (before-indent min)
(wordcount (read-number "How many words in a line? " 7))
(delimiter
(read-string "Delimit with (default: \" + \") "
nil nil "\" + \"")))
(save-excursion
(goto-char min)
(while (< min max)
(incf counted)
(when (= counted wordcount)
(insert delimiter)
(backward-char)
(incf max (length delimiter))
(setq before-indent (point)
counted 0)
(newline-and-indent)
(incf max (- (point) before-indent)))
(forward-word)
(setq min (point))))))
The use should be straight forward. Also check your editing mode for a <mode>-insert-and-indent function, you would like to use it instead of newline-and-indent.

Related

Writing major mode: how set different start string and end string character?

I'm writing a major mode where I can have multiline strings like this:
Text : >abcde
fgh
ijklmonp<
where '>' and '<' indicate the respective start and end of the string. The following syntax table entries only mark >...> and <...< strings, which is not what I want.
(modify-syntax-entry ?> "\"" st)
(modify-syntax-entry ?< "\"" st)
Currently the best solution is using generic string delimiters: ‘|’, but it still messes up my system as I have >...<...< situations sometimes. The best would be if I could use a multiline regexp like
^Text : >.*<$
How can I achieve this?
As thornjad explains, this is not supported directly by syntax-table, so you need to use syntax-propertize-function. E.g.
(defconst my-syntax-propertize
(syntax-propertize-rules
(">" (0 (unless (nth 8 (save-excursion (syntax-ppss (match-beginning 0)))
(string-to-syntax "|"))))
("<" (0 (when (eq t (nth 3 (save-excursion
(syntax-ppss (match-beginning 0))))
(string-to-syntax "|"))))))
then in your major mode function:
(setq-local syntax-propertize-function my-syntax-propertize)
The nth 8 test makes sure > is only marked as a string delimiter if it is not within another string or comment, and the nth 3 test makes sure that < is only marked as a string delimiter when it occurs with a string that was started by another generic string delimiter.
Unfortunately modify-syntax-entry isn't powerful enough to handle this sort of situation. Luckily we have other options! My orson-mode deals with a similar issue where strings are delimited by double-single quotes ('') instead of double quotes (").
To do this, a regexp looks for the entire string, quotes included, then uses Emacs's string-fence class to mark the quotes as fences.
(defconst orson--string-rx
"\\(''[^']*''\\)")
(defun orson-syntax-propertize-function (start end)
(save-excursion
(goto-char start)
(while (re-search-forward orson--string-rx end 'noerror)
(let ((a (match-beginning 1))
(b (match-end 1))
(string-fence (string-to-syntax "|")))
(put-text-property a (1+ a) 'syntax-table string-fence)
(put-text-property (1- b) b 'syntax-table string-fence))))

un-camelCase code not working

camelCase.el emacswiki has a function to un-camelcase. But It doesn't seem to work. I added that piece to the camelCase.el itself. But can't get it to work.
What am I missing ? Did anyone else have the same problem ?
EDIT : I have added last two functions, one of which is the function that doesn't work
(defun camelCase-downcase-word (count)
"Make word starting at point lowercase, leaving point after word."
(interactive "*p")
(let ((start (point)))
(camelCase-forward-word count)
(downcase-region start (point))))
(defun un-camelcase-string (s &optional sep start)
"Convert CamelCase string S to lower case with word separator SEP.
Default for SEP is a hyphen \"-\".
If third argument START is non-nil, convert words after that
index in STRING."
(let ((case-fold-search nil))
(while (string-match "[A-Z]" s (or start 1))
(setq s (replace-match (concat (or sep "_")
(downcase (match-string 0 s)))
t nil s)))
(downcase s)))
(provide 'camelCase)
Other than the misleading doc-string (it actually defaults to "_", not "-" for the separator), the definition of un-camelcase-string you provide works. Can you give us more details about how it fails and under what circumstances?

Context-sensitive font-locking in emacs

Basically, I'm trying to syntax highlight the following piece of coffeescript code the way I want it. Explanation of the syntax of coffeescript functions can be found here.
nameHere = (tstamp, moo, boo) ->
...
The names tstamp, moo and boo should be colored pink (and nothing else, not the commas and not the brackets) because they are parameters to a lambda function.
highOrderFun ((x) -> x * x) someList
Here it is the first x that is the parameter. Parameters can have default arguments:
class Foo
meth: (msg = "Hello", bar = "foo") ->
....
Default arguments can be variables themselves:
defColor = "red"
print = (msg, color = defColor) ->
...
So msg and color above should be highlighted, but not defColor. An even trickier case is functions with default arguments that themselves are functions. I think that is to hard for emacs' font-lock to highlight correctly, but I'm including it anyway:
funTakingFuns = (f1 = ((a, b) -> a*b), f2 = ((c, d) -> c/d)) ->
...
This appears to be pretty complicated to achieve in emacs because you want the highlighting to be context sensitive. I've read up on the documentation on font-lock but haven't been able to figure it out.
I'd be grateful if someone could show me what to set font-lock-defaults to make it syntax highlight the way I want it.
Update Showing more coffeescript syntax examples.
font-lock-keywords allows function values in the MATCHER field:
where MATCHER can be either the regexp to search for, or the function name to
call to make the search (called with one argument, the limit of the search;
it should return non-nil, move point, and set match-data appropriately if
it succeeds; like re-search-forward would).
So we need to write a function that would search for the next function argument in the buffer.
Something like this:
(defun coffee-match-next-argument (limit)
(let ((start (point)))
;; Look for the arrow.
(when (re-search-forward ") *->" limit t)
;; Save the position of the closing paren.
(let ((stop (point)))
(goto-char (match-beginning 0))
;; Go to the opening paren.
(goto-char (nth 1 (syntax-ppss)))
;; If we're before our initial position, go forward.
;; We don't want to find the same symbols again.
(when (> start (point))
(goto-char start))
;; Look for the next symbol until the arrow.
(or (re-search-forward "\\((\\|,\\) *\\(\\(\\sw\\|_\\)+\\)" stop 'mv)
(coffee-match-next-argument limit))))))
And the setup, to use with existing coffee-mode:
(font-lock-add-keywords
'coffee-mode
'((coffee-match-next-argument 2 font-lock-variable-name-face)))
You can also use this in font-lock-defaults, of course.
This will likely use some other color than pink, but that's easy to change.
This is more kind of a hack, it's far from optimal (as I am not familiar at all with coffeescript), but perhaps with a little tweaking yourself, you can get this done.
All the ingredients are there.
The triggering of the commands/functions are based on the assumption that you use coffee-mode.
If you do not, this is not a big trouble, you'll just have to hook these things differently.
Put the following line in your .emacs:
(eval-after-load 'coffee '(load "/PATH/custom-coffee-font-lock.el"))
You can just save the below text as a file, and it will:
(1) Font lock when you trigger coffee-mode
(2) Font lock current line when you type the ">" as part of "->"
(3) Allow to font-lock the buffer by running M-x coffee-init-font-lock
;;;; custom-coffee-font-lock
;; Firstly, create a new font for this.
(make-face 'font-lock-coffeescript-face)
(set-face-foreground 'font-lock-coffeescript-face "pink")
;; Next, one function that should be ran after a file is identified as
;; a coffeescript file. It will do the font-locking you want on
;; the whole buffer. It is also possible to run it manually.
(defun coffee-init-font-lock ()
(interactive)
(save-excursion
(goto-char 1)
(while (search-forward-regexp "=.+->" nil t)
(search-backward-regexp "(")
(forward-char 1)
(add-text-properties
(point) (- (search-forward-regexp "," nil nil) 1)
'(font-lock-face font-lock-coffeescript-face))
(add-text-properties
(point) (- (search-forward-regexp "," nil nil) 1)
'(font-lock-face font-lock-coffeescript-face))
(add-text-properties
(point) (- (search-forward-regexp ")" nil nil) 1)
'(font-lock-face font-lock-coffeescript-face))
(move-end-of-line 1)))
)
;; This actually runs that function.
(coffee-init-font-lock)
;; This advice will be ran everytime you write something. It will check
;; whether "->" is before it, so when you type the final ">", it will
;; do the font locking for the current line (it also checks for your mode).
(defadvice self-insert-command (after coffee-font-lock activate)
(when (and (looking-back "->") (eq major-mode 'coffee-mode))
(save-excursion
(search-backward-regexp "(")
(forward-char 1)
(add-text-properties
(point) (- (search-forward-regexp "," nil nil) 1)
'(font-lock-face font-lock-coffeescript-face))
(add-text-properties
(point) (- (search-forward-regexp "," nil nil) 1)
'(font-lock-face font-lock-coffeescript-face))
(add-text-properties
(point) (- (search-forward-regexp ")" nil nil) 1)
'(font-lock-face font-lock-coffeescript-face))))
)
(provide 'custom-coffee-font-lock)
;;; custom-coffee-font-lock.el
If you have any requests, let me know. Like I said, I do not use CoffeeScript, so this might throw huge errors your way. At the very least it should help with some basic ideas.
Result:

How to finish this job in emacs?

The original string is like this:
# chrom,name,strand,txStart
And the result should looks like this:
# $1: chrom
# $2: name
# $3: strand
# $4: txStart
Does anyone have idea of a quick way to do that?
Lots of ways.
You could use a search and replace making use of the \# counter in the replacement. That's zero-based, so you'd either need to add a dummy replacement at the front to use up the zero, or else use the elisp replacement expression \,(1+ \#) instead.
You could use a keyboard macro, and insert a counter with C-xC-kTAB or <f3>. You can seed that counter by supplying a prefix argument when you start recording.
On Emacs 24 you can number the lines of a marked region using a custom format string with C-uC-xrN, so your format string could be # $%1d:
Evaluate following code and execute foo function on input line.
(require 'cl)
(defun foo ()
(interactive)
(let* ((str (buffer-substring-no-properties
(line-beginning-position) (line-end-position)))
(words-str (and (string-match "# \\(.+\\)$" str)
(match-string 1 str)))
(buf (get-buffer-create "*tmp*")))
(unless words-str
(error "Line should be '# word1,word2,...'"))
(with-current-buffer buf
(erase-buffer)
(loop with index = 1
for word in (split-string words-str ",")
do
(progn
(insert (format "# $%d: %s\n" index word))
(incf index)))
(pop-to-buffer buf))))

Emacs: capture paragraphs and act on each

Quite often I need to capture some paragraphs in a region with regexp - and then act on each paragraph.
For example consider a problem of recovering a numberd list:
1. Some text with a blank
line. I want not to have that line break
2. Some more text. Also - with
a line break.
3. I want to have a defun which
will capture each numbered entry
and then join it
I want to write a defun which will make the previous text like that:
1. Some text with a blank line. I want not to have that line break
2. Some more text. Also - with a line break.
3. I want to have a defun which will capture each numbered entry and then join it
Here's my best try for now:
(defun joining-lines (start end)
(interactive "r")
(save-restriction
(narrow-to-region start end)
(goto-char (point-min))
(while (search-forward-regexp "\\([[:digit:]]\\. \\)\\(\\[^[:digit:]\\].*?\\)" nil t)
(replace-match "\\1\\,(replace-regexp-in-string " ;; here's a line break
" " " (match-string 2))" t nil))
)
)
It neither work - nor give an error.
Actually it would be better to have a separate defun to act on a string. This way it will be easy to expand the code to have multiple substitutions on the replace-match.
There are two issues with your code:
A period in a regexp matches "anything except newline," so your .*? will never include a newline character.
The \,(...) regexp replacement construct is only available interactively. If issue #1 were resolved, you'd get an error (error "Invalid use of '\\' in replacement text"). Programmatically, you have to write the code yourself, eg: (replace-match (concat (match-string 1) (replace-regexp-in-string "\n" " " (match-string 2)))).
I think you'd be better off not relying on regexps to do the heavy lifting here. This works for me:
(defun massage-list (start end)
(interactive "r")
(save-excursion
(save-restriction
(narrow-to-region start end)
(goto-char start)
(while (progn (forward-line) (= (point) (line-beginning-position)))
(when (not (looking-at "^[[:digit:]]+\\."))
(delete-indentation)
(beginning-of-line))))))
Try something like this code. It's not the shortest possible but rather something straigthforward.
(defun joining-lines(start end)
(interactive "r")
(let ((newline-string "~~~"))
(save-restriction
(narrow-to-region start end)
(mark-whole-buffer)
(replace-string "\n" newline-string)
(goto-char start)
(while (re-search-forward (concat newline-string "\\([[:digit:]]+. \\)") nil t)
(replace-match "\n\\1" nil nil))
(mark-whole-buffer)
(replace-string newline-string " "))))
Here's a solution using an external defun:
(defun capturing-paragraphs (start end)
(interactive "r")
(save-restriction
(narrow-to-region start end)
(goto-char (point-min))
(while (search-forward-regexp "^\\(^[[:digit:]]+\\.[^[:digit:]]+$\\)" nil t) (replace-match (multiple-find-replace-in-match) t nil))))
(defun multiple-find-replace-in-match ()
"Returns a string based on current regex match."
(let (matchedText newText)
(setq matchedText
(buffer-substring-no-properties
(match-beginning 1) (match-end 1)))
(setq newText
(replace-regexp-in-string "\n" "" matchedText) )
newText))
it works only if there's no figures in the text. But this solution is straighforward to expand - to add new replacements on a matched string.