I have a plain text file with multiple patterns. Example:
DEBUG: i'm a debug line
DEBUG: Another 1
ERROR: this was an error
DEBUG: Another 2
NORMAL: EMACS
DEBUG: Another 3
ERROR: another error
The idea is to use occur-mode to filter the text file with the patterns i want. Example: DEBUG and ERROR.
As far as i understood occur only works with single string entry or regex.
How can i use the occur mode to filter more than one string pattern ? If there is another emacs mode to filter strings in text i also accept.
You can pass a regexp that matches either of the strings to occur. E.g., type M-x occur RET DEBUG\|ERROR.
If it is a pattern you often use, here's a bit of elisp (based on legoscia's answer):
(defun myoccur (arg)
(interactive "sList of space-separated args: ")
(occur (s-replace " " "\\|" arg))
)
it replaces the whitespaces with the OR regexp construct and calls occur.
ps: s-replace is not standard. You need (require 's), the s.el library. https://github.com/magnars/s.el
Related
Two of my favorite Vim features are the ability to apply standard operators to lines matching a regex, and the ability to filter a selection or range of lines through an external command. But can these two ideas be combined?
For example, I have a text file that I use as a lab notebook, with notes from different dates separated by a line of dashes. I can do something like delete all the dash-lines with something like :% g/^-/d. But let's say I wanted to resize all the actual text lines, without touching those dash lines.
For a single paragraph, this would be something like {!}fmt. But how can this be applied to all the non-dash paragraphs? When I try what seems the logical thing, and just chain these two together with :% v/^-/!fmt, that doesn't work. (In fact, it seems to crash Vim...)
Is there a way to connect these two ideas, and only pass lines (not) matching a pattern into an external command like fmt?
Consider how the :global command works.
:global (and :v) make two passes through the buffer,
first marking each line that matches,
then executing the given command on the marked lines.
Thus if you can come up with a command – be it an Ex command or a command-line tool – and an associated range that can be applied to each matching line (and range), you have a winner.
For example, assuming that your text is soft-wrapped and your paragraphs are simply lines that don't begin with minus, here's how to reformat the paragraphs:
:v/^-/.!fmt -72
Here we used the range . "current line" and thus filtered every matching line through fmt. More complicated ranges work, too. For instance, if your text were hard-wrapped and paragraphs were defined as "from a line beginning with minus, up until the next blank line" you could instead use this:
:g/^-/.,'}!fmt -72
Help topics:
:h multi-repeat
:h :range!
:h :range
One way to do it may be applying the command to the lines matching the pattern 'not containing only dashes'
The solution I would try the is something like (not tested):
:g/\v^(-+)#!/normal V!fmt
EDIT I was doing some experiments and I think a recurvie macro should work for you
first of all set nowrapscan:
set nowrapscan
To prevent the recursive macro executing more than you want.
Then you make a search:
/\v^(-+)#!
Test if pressing n and p works with your pattern and tune it up if needed
After that, start recording the macro
qqn:.!awk '{print $2}'^M$
In this case I use awk as an example .! means filter current line with an external program
Then to make the macro recursive just append the string '#q' to the register #q
let #q .= '#q'
And move to the beggining of the buffer to apply the recursive macro and make the modifications:
gg#q
Then you are done. Hope this helps
Given the following file path:
/Users/Lawrence/MyProject/some/very/interesting/Code.scala
I would like to generate the following using a single regex replace (the root can be a constant):
some.very.interesting
This is for the purpose of generating a snippet for Sublime Text which can automatically insert the correct package/namespace header for my scala/java classes :)
Sublime Text uses the following syntax for their regex replace patterns (aka 'substitutions'):
{input/regex/replace/flags}
Hence why an iterative approach cannot be taken - it has to be done in one pass! Also, substitutions cannot be nested :(
If you know the maximum number of nested folders.You can specify that in your regex.
For 1 to 3 nested folders
Regex:/Users/Lawrence/MyProject/(\w+)/?(\w+)?/?(\w+)?/[^/]+$
Replace:$1.$2.$3
For 1 to 5 nested folders
Regex:/Users/Lawrence/MyProject/(\w+)/?(\w+)?/?(\w+)?/?(\w+)?/?(\w+)?/[^/]+$
Replace:$1.$2.$3.$4.$5
Given the constraints this is only thing you can do
Input
/Users/Lawrence/MyProject/some/very/interesting/Code.scala
Regex
^/Users/Lawrence/MyProject/[^/]+/[^/]+/[^/]+/Code.scala
or
^/[^/]+/[^/]+/[^/]+/([^/]+)/([^/]+)/([^/]+)/
Replace
\1.\2.\3
Update
This gets you closer, but not exactly it:
Regex
(^/Users/Lawrence/MyProject/|/Code\.scala$|/)
Replacement
.
Output would be:
.some.very.interesting.
Without multiple replacements in a single line and without recursive back references it's going to be hard.
You might have to do a second replacement, replacing something like this with an empty string (if you can):
(^\.|\.$)
i have a text file in a particular format..
!c_xyz|crby=112|crdate=12jun11|mdby=112|mddate=12jun11|Desc=xyz
asdasda........................................................
asddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
!c_abc|crby=112|crdate=12jun11|mdby=112|mddate=12jun11|Desc=xyz...
I need a regular expression to reformat this file using Find and Replace - Visual Studio. The Desc field value has overflowed onto next lines. i need to move them back to the actual line. Final string should be like
!c_xyz|crby=112|crdate=12jun11|mdby=112|mddate=12jun11|Desc=xyzsdasda.........asdddddd..
!c_abc|crby=112|crdate=12jun11|mdby=112|mddate=12jun11|Desc=xyz...
I need an RE for "desc=" followed by anything until the next ! symbol
find Desc=([^\|\r\n]+)[\r\n](([^!\r\n][^\r\n]+[\r\n])*), replace with Desc=\1\2 and repeat until every line starts with ! (you can test this using ^[^!] as a search expr which should find nothing).
alternatively find [\r\n]+, replace with the empty string. thereafter find !, replace with \r\n!. this suggestion has 2 drawbacks. it temporarily produces very long lines which your editor (notably vs) may or may not have difficulties with and processes descriptions containing ! incorrectly.
addendum:
your input seems to be fixed format up to the Desc section. if it is indeed, you can apply alternative #2, step 1, being followed by a search/replace run using (!.{53}\|Desc=)/[\r\n]\1.
As mentioned in the comments by #X3074861X, you can use Notepad++.
Input:
!c_xyz|crby=112|crdate=12jun11|mdby=112|mddate=12jun11|Desc=xyz
asdasda........................................................
asddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
!c_abc|crby=112|crdate=12jun11|mdby=112|mddate=12jun11|Desc=xyz...
For the find and replace, select the mode as Regular expression with the options as follows:
Find what: \r\n[^!]
Leave Replace with blank.
Output:
!c_xyz|crby=112|crdate=12jun11|mdby=112|mddate=12jun11|Desc=xyzsdasda........................................................sddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
!c_abc|crby=112|crdate=12jun11|mdby=112|mddate=12jun11|Desc=xyz...
Screenshot:
I have a similar problem to that addressed in
Emacs: regular expression replacing to change case
I want to use Emacs' file browser mode Dired to rename a file from 08 - hey you.mp3 to 08 - Hey you.mp3.
I type % R to replace ^\([0-9]* - \)\([a-z]\)\(.*\)$ by \1\,(upcase \2)\3 and I get an error
Invalid use of `\' in replacement text
When I query-replace-regexp a similar regexp \([0-9]* - \)\([a-z]\)\(.*\) by \1\,(upcase 2)\3 in a normal text buffer I don't have problems. The only input difference are the enclosing ^ and $, that are required as explained in http://www.gnu.org/software/emacs/manual/html_node/emacs/Transforming-File-Names.html#Transforming-File-Names, however the source of error seems to be the \,(upcase ), which seems not usable in Dired, since I don't have this error when I use for example \1\3\2as replace regexp.
I am using Emacs 23.2.1
% R in dired calls dired-do-rename-regexp which ends up calling replace-match from dired-string-replace-match, and replace-match does not support elisp replacements.
What you can do is take advantage of wdired which allows you to edit the directory listing as plain text.
C-xC-q (i.e. the usual toggle-read-only binding) will toggle between dired and wdired. Once in wdired, you can use a normal search and replace, including the elisp replacement pattern.
So I have a tool lints python changes I've made and produces errors and warnings. I would like this to be usable in compile mode with Emacs, but I have an issue. The file name is output only once at the beginning, and then only line numbers appear with the errors and warnings. Here's an example:
Linting file.py
E0602: 37: Undefined variable 'foo'
C6003: 42: Unnecessary parens after 'print' keyword
2 new errors, 2 total errors in file.py.
It's very similar to pylint, but there's no output-format=parseable option. I checked the documentation for compilation-error-regexp-alist, and found something promising:
If FILE, LINE or COLUMN are nil or that index didn't match, that
information is not present on the matched line. In that case the
file name is assumed to be the same as the previous one in the
buffer, line number defaults to 1 and column defaults to
beginning of line's indentation.
So I tried writing a regexp that would optionally match the file line and pull it out in a group, and then the rest would match the other lines. I assumed that it would first match
Linting file.py
E0602: 37: Undefined variable 'foo'
and be fine. Then it would continue and match
C6003: 42: Unnecessary parens after 'print' keyword
with no file. Since there was no file, it should use the file name from the previous match right? Here's the regexp I'm using:
(add-to-list 'compilation-error-regexp-alist 'special-lint)
(add-to-list 'compilation-error-regexp-alist-alist
'(special-lint
"\\(Linting \\(.*\\)\\n\\)?\\([[:upper:]][[:digit:]]+:\\s-+\\([[:digit:]]\\)+\\).*"
2 4 nil nil 3))
I've checked it with re-builder and manually in the scratch buffer. It behaves as expected. the 2nd group is the file name, the 4th is the line number, and the 3rd is what I want highlighted. Whenever I try this, I get the error:
signal(error ("No match 2 in highlight (2 compilation-error-face)"))
I have a workaround for this that involves transforming the output before the compile module looks at it, but I'd prefer to get rid of that and have a "pure" solution. I would appreciate any advice or pointing out any dumb mistakes I may have made.
EDIT
Thomas' pseudo code below worked quite well. He mentioned that doing a backwards re search could mess up the match data, and it did. But that was solved by adding the save-match-data special form before save-excursion.
FILE can also have the form (FILE
FORMAT...), where the FORMATs (e.g.
"%s.c") will be applied in turn to the
recognized file name, until a file of
that name is found. Or FILE can also
be a function that returns (FILENAME)
or (RELATIVE-FILENAME . DIRNAME). In
the former case, FILENAME may be
relative or absolute.
You could try to write a regex that doesn't match the file name at all, only the column. Then for the file, write a function that searches backwards for the file. Perhaps not as efficient, but it should have the advantage that you can move upwards through the error messages and it will still identify the correct file when you cross file boundaries.
I don't have the necessary stuff installed to try this out, but take the following pseudo-code as an inspiration:
(add-to-list 'compilation-error-regexp-alist-alist
'(special-lint
"^\\S-+\\s-+\\([0-9]+\\):.*" ;; is .* necessary?
'special-lint-backward-search-filename 1))
(defun special-lint-backward-search-filename ()
(save-excursion
(when (re-search-backward "^Linting \\(.*\\)$" (point-min) t)
(list (match-string 1)))))
(It could be that using a search function inside special-lint-backward-search-filename will screw up the sub-group matching of the compilation-error-regexp, which would suck.)
I don't think you can make compilation do what you want here, because it won't assume that a subsequent error relates to a previously-seen filename. But here's an alternative; write a flymake plugin. Flymake always operates on the current file, so you only need to tell it how to find line (and, optionally, column) numbers.
Try hacking something like this, and you'll likely be pleasantly surprised.