Spacemacs/Evil backward delete from line end - spacemacs

In Vim if I need to change the last word in line (ex. word "bar") when cursor is at the end (char "r"):
foo bar<cursor>
nextLine
I type `lcb' and get:
foo <cursor>
nextLine
But in Spacemacs after lcb (I have (setq-default evil-cross-lines t)
in config so l doesn't stop at the line end) the linebreak char is deleted too and I get:
foo <cursor>nextLine
Is there any option in Evil to get the Vim behaviour?

Related

Is there any good way to read numbers in square brackets in Lua?

In Lua, Is there any good way to read Only numbers from input like "[1,2,3,4]" if i know the number of the numbers
I did io.read("*n") for each, but that just returns nil values
local num = io.read()
for i = 1, num do
print(io.read("*n"))
end
for that code inputs are
4
[1,1,15,54]
outputs are
nil
nil
nil
nil
I expect
1
1
15
54
Should I just use string.find and sub with ',' ?
If you're sure that there are no spaces in the input, you can use this code:
local num = io.read()
for i = 1, num do
io.read(1)
print(io.read("*n"))
end
The first io.read(1) reads [, the next ones read the commas. The closing ] is left unread.
Reading the whole line and parsing it is more robust:
local num = io.read()
local lin = io.read()
local i=0
for w in lin:gmatch("%d+") do
i=i+1
print(i,w)
end

AWK script to process information spread over multiple file lines

I am trying to do a text processing script, for what seems to be a rather simple task.
I have a file, which contains the following repeated pattern
111 0 1000 other stuff #<- here a new element begins
some text & #<- "&" or white spaces increment -
some more #<- signal continue on next line
last line
221 1 1.22E22 # new element $2!=0 must be followed by float
text &
contiuned text
c comment line in between
more text &
last line
2221 88 -12.123 &
line1
line2
c comment line
last line
223 0 lll -111 $ element given by line
22 22 -3.14 $ element given by new line
I would like to get
111 0 1000 other stuff #<- here a new element begins
some text & #<- "&" or white spaces increment -
some more #<- signal continue on next line
last line &
xyz=1
221 1 1.22E22 # new element $2!=0 must be followed by float
text &
contiuned text
c comment line in between
more text &
last line &
xyz=1
2221 88 -12.123 &
line1
line2
c comment line
last line &
xyz=1
223 0 lll -111 & $ element given by line
xyz=1
22 22 -3.14 & $ element given by new line
xyz=1
I would like to develop an awk script that appends a string to the last line of each element. To do so my script looks for the new element pattern, and continues to read until one of the next element indicators are found. Unfortunately, it does not function properly because it prints the last line two times and fails to append to the very last line of the file.
function newelement(line) {
split(line, s, " ")
if (s[1] ~/^[0-9]+$/ && ((s[2] ~/^[0-9]+$/ && s[3] ~/\./) || (s[2] == 0 && s[3] !~/\./))) {
return 1
} else {
return -1
}
}
function contline(line) {
if (line~/&/ || line~/^[cC]/ || line~/^\s{3,10}[^\s]./) {
return 1
} else {
return -1
}
}
BEGIN {
subs = " xyz=1 "
} #increment to have the next line in store
FNR == 1 {
getline nextline < FILENAME
}
{
# get the next line
getline nextline < FILENAME
if (newelement($0) == 1 && NR < 3673) {
if (length(old) > 0 || $0~/^$/) {
printf("%s &\n%20s\n", old, subs)
print $0
}
# to capture one line elements with no following continuation
# i.e.
# 221 91 0.5 33333
# 22 0 11
#look at the next line
else if (($0!~/&/ && contline(nextline) == -1)) {
printf("%s &\n%20s\n", $0, subs)
}
}
else {
print "-" $0
}
# store last not - commented line
if ($0!~/^\s{0,20}[cC]/) old = $0
}
Where the comment line has c or c followed by an empty space. Comment lines should be preserved but no strings should be appended to them.
Please check the following code and let me know if it works for you:
$ cat 3.1.awk
BEGIN{
subs = " xyz=1 "
threshold = 3673
}
# return boolean if the current line is a new element
function is_new_element(){
return ($1~/^[0-9]+$/) && (($2 ~ /^[0-9]+$/ && $3~/\./) || ($2 == 0 && $3 !~/\./))
}
# return boolean if the current line is a comment or empty line
function is_comment() {
return /^\s*[cC] / || /^\s*$/
}
# function to append extra text to line
# and followed by comments if applicable
function get_extra_text( extra_text) {
extra_text = sprintf("%s &\n%20s", prev, subs)
text = (text ? text ORS : "") extra_text
if (prev_is_comment) {
text = text ORS comment
prev_is_comment = 0
comment = ""
}
return text
}
NR < threshold {
# replace the above line with the following one if
# you want to process up to the first EMPTY line
#NR==1,/^\s*$/ {
# if the current line is a new element
if (is_new_element()) {
# save the last line and preceeding comments
# into the variable 'text', skip the first new element
if (has_hit_first_new_element) text = get_extra_text()
has_hit_first_new_element = 1
prev_is_new = 1
# before hitting the first new_element line, all lines
# should be printed as-is
} else if (!has_hit_first_new_element) {
print
next
# if current line is a comment
} else if (is_comment()) {
comment = (comment ? comment ORS : "") $0
prev_is_comment = 1
next
# if the current line is neither new nor comment
} else {
# if previous line a new element
if (prev_is_new) {
print (text ? text ORS : "") prev
text = ""
# if previous line is comment
} else if (prev_is_comment) {
print prev ORS comment
prev_is_comment = 0
comment = ""
} else {
print prev
}
prev_is_new = 0
}
# prev saves the last non-comment line
prev = $0
next
}
# print the last block if NR >= threshold
!is_last_block_printed {
print get_extra_text()
is_last_block_printed = 1;
}
# print lines when NR > threshold or after the first EMPTY line
{ print "-" $0 }
Where
The lines are divided into 3 categories and processed differently:
is_new_element() to true when the current line is a new element, the flag prev_is_new identify the previous new element
is_comment() function to true, then the current line is a comment, prev_is_comment to identify the previous comment line
other lines: all other lines except the above two
Others notes:
You can select a NR < threshold(which is 3673 in your code), or a range pattern NR==1,/^\s*$/ to process only a range of lines.
is_last_block_printed flag and related code are to make sure the last processing block is printed either at the end of the above range or in the END{} block
I did not check the trailing & for the continuing line, if they are followed by a comment or a new element, the logic has to be defined, i.e. which one should take precedence
If there are other lines before the first is_new_element() line, the code will not work well. This can be fixed by adding another flag instead of using if (NR > 1) to update text.
Testing Sample:
$ cat 3.1.txt
111 0 1000 other stuff #<- here a new element begins
some text & #<- "&" or white spaces increment -
some more #<- signal continue on next line
last line
221 1 1.22E22 # new element $2!=0 must be followed by float
text &
contiuned text
c comment line in between
more text &
last line
2221 88 -12.123 &
line1
line2
c comment line 1
last line
c comment line 2
c comment line 3
c comment line 4
c comment line 5
223 0 lll -111
223 0 22 -111
223 0 22 -111
c comment line in between 1
c comment line in between 2
22 22 -3.14
c comment line at the end
Output:
$ awk -f 3.1.awk 3.1.txt
111 0 1000 other stuff #<- here a new element begins
some text & #<- "&" or white spaces increment -
some more #<- signal continue on next line
last line &
xyz=1
221 1 1.22E22 # new element $2!=0 must be followed by float
text &
contiuned text
c comment line in between
more text &
last line &
xyz=1
2221 88 -12.123 &
line1
line2
c comment line 1
last line &
xyz=1
c comment line 2
c comment line 3
c comment line 4
c comment line 5
223 0 lll -111 &
xyz=1
223 0 22 -111 &
xyz=1
223 0 22 -111 &
xyz=1
c comment line in between 1
c comment line in between 2
22 22 -3.14 &
xyz=1
c comment line at the end
Some extra explanantion:
One concern to process the text is the trailing newline "\n" when appending subs to prev line. it's especially important when consecutive new_element lines happen.
Important to notice, the variable prev in the code is defined as the previous non-comment line (category-1, 3 defined above). there could be zero or multiple comment (category-2) lines between the prev line and the current line. that's also why we use print prev ORS comment instead of print comment ORS prev when printing regular comments (not those preceding the new_element line).
A block of comment lines (1 or more consecutive comment lines) are saved into the variable comment. if it's right before the new_element line, then append the block to the variable text. All other block of comments will be printed in the line print prev ORS comment mentioned above
The function get_extra_text() is to process the extra_text, which is in the order: prev subs ORS comments, where comments is appended only when prev_is_comment flag is 1. Do notice that the same variable text could have saved multiple prev subs ORS comments blocks if there are consecutive new_element lines.
We only print on the category-3 line mentioned above(neither a new_element nor a comment). This is a safe place when we have no worry about the trailing newline or extra_text:
if the prev_is_new, we print the cached text and then the variable prev (which is a new_element)
if the prev_is_comment, we just print the prev ORS comment. notice again the variable prev saves the last non-comment line from the current line, it does not have to be the line right above the current line.
all other case, just print the prev line as-is
Since we are concatenating lines into text and comment variables, we use the following syntax to avoid the leading ORS (which is "\n" by default)
text = (text ? text ORS : "") prev
If the leading ORS is not a concern, you can just use the following:
text = text ORS prev
and because the lines are appended to these variables, we will need to reset
them (i.e. text = "") each time after we consume them, otherwise, the
concatenated variable will contain all previously processed lines.
Final notes
added a flag has_hit_first_new_element, in case there are lines before the first new_element line, they will be printed as-is. In this code, the first new_element line should be treated differently, using NR==1 is not a safe-belt.
removed the code in the END{} block which is redundant
Try this:
function newelement(line){
split(line,s," ")
if(s[1]~/^[0-9]+$/ && ((s[2]~/^[0-9]+$/ && s[3]~/\./)|| (s[2]==0 && s[3]!~/\./))){return 1}
else{return -1}
}
BEGIN{
subs=" xyz=1 "
}
{
if (length($0)==0) next # Skip empty lines, remove or change it according to your needs.
if (newelement($0)==1){
if (length(last_data)>0) {
printf("%s &\n%20s\n",last_data,subs)
if (last_type=="c") {
print comments
}
}
last_data=$0
last_type="i"
} else if($0 ~/^\s*[cC] /) {
if (last_type=="c") comments = comments ORS $0
else comments = $0
last_type="c"
} else {
if (last_type=="c") print comments
else if(length(last_data)>0) print last_data
last_data=$0
last_type="d"
}
}
END{
printf("%s &\n%20s\n",last_data,subs)
if (last_type=="c") print comments
}
Three variables:
last_data to hold last data line.
last_type to hold the type of last line, i for indicator, c for comments.
comments to hold comments line(s).

Remove Double Quotes While Reading CSV Files in VBA

In VBA, I need to import a few R generated CSV files. However, the split function did not work properly and gaveType mismatch. My best guess is that: VBA added double quotes between each imported line. So the first line becomes " 47.27284, 130.5583, 44.826609, 189.905367". I tried to remove double quotes using replace or remove the first and last character but the error still existed. Any suggestions to deal with this issue?
CSV file
dose_BMD_r, dose_ED_r, dose_BMD_c, dose_ED_c
47.27284, 130.5583, 44.826609, 189.905367
47.27284, 130.5583, 52.226171, 233.338840
47.27284, 130.5583, 8.484266, 6.887616
VBA code
lin_ind = 1
Open text_fn For Input As #1
Do Until EOF(1)
Line Input #1, textline
If lin_ind = 1 Then
'Do nothing
Else
textline_1 = Split(textline, ",")
End If
lin_ind = lin_ind + 1
Loop
Close #1
Split function returns array. So the variable where you store Split's return value, should be array/variant.
Declare it as Dim textline_1 that's it. It will work.
OR Dim textline_1 () As String

Not completed file read

I'm trying to debug what went wrong in my code. My file.txt contains 1763 lines but when I run it, it always ends up not completed. Always stops somewhere at 1680 and up (printed by the row in my code); the thing is it stops at different line every time I run it, so I don't think the problem's with my text file.
row = 0
for line in io.lines("file.txt") do
row = row+1
local new_row1 = {}
for n in line:gmatch'%S+' do
table.insert(new_row1, tonumber(n))
end
if #new_row1 > 0 then
table.insert(input, new_row1)
end
print(row)
end
Is there something wrong in my code?
It looks like in your code, you opened a file handle to "file.txt" at the beginning of your script and it remains open till the end where you close the file. During that time, you attempt to reopen "file.txt" again in your loop which is causing the strange behavior you're seeing.
When I moved your file open and close scopes to the middle section after first loop but before the last outer loop, that fixes the issue:
file = assert(io.open("file.txt", "w"))
for i = 1, 1000 do
j = math.random(i, row-one)
u[i], u[j] = u[j], u[i]
for k = 1, 11 do
file:write(input2[u[i]][k], " ")
end
file:write"\n"
end
num = (row-one)+1
for i = 1, one do
for k=1, 11 do
file:write(input2[num][k], " ") --writes to the file all the rows starting from where '1' in column11 was seen
end
file:write("\n")
num = num + 1
end
file:close()
-----------------------------------Access file.txt.--------------------------
-- ...
This gives the expected output:
Done 1762 1762
--------------------------

Lua Script Pattern Matching Problem

First of all, I have been using this site as a reference through the entire scripting process and it has been wonderful. I appreciate how useful and knowledgeable everyone is here. With that in mind, I have a question regarding matching (pattern matching) in Lua. I am writing a script that essentially takes input from a file and imports it into a table. I am checking for specific MAC addresses in the file as the host I am querying.
if macFile then
local file = io.open(macFile)
if file then
for line in file:lines() do
local f = line
i, j = string.find ( f, "%x+" )
m = string.sub(f, i, j)
table.insert( macTable, m )
end
file:close()
end
This parses the file into a format I will use to query later. Once the table is built, I run a pattern matching sequence to try and match the MAC from the table by iterating the table and matching the pattern against the current iteration:
local output = {}
t = "00:00:00:00:00:00"
s = string.gsub( t, ":", "")
for key,value in next,macTable,nil do
a, p = string.find ( s, value )
matchFound = string.sub(s, a, p)
table.insert( output, matchFound )
end
This doesn't return any output although when I enter it line by line in a Lua prompt, it seems to work. The variables are being passed correctly I believe. Any suggestions?
If your macFile uses a structure like this:
012345678900
008967452301
000000000000
ffffffffffff
The following script should work:
macFile = "./macFile.txt"
macTable = {}
if macFile then
local hFile = io.open(macFile, "r")
if hFile then
for line in hFile:lines() do
local _,_, sMac = line:find("^(%x+)")
if sMac then
print("Mac address matched: "..sMac)
table.insert(macTable, sMac)
end
end
hFile:close()
end
end
local output = {}
t = "00:00:00:00:00:00"
s = string.gsub( t, ":", "")
for k,v in ipairs(macTable) do
if s == v then
print("Matched macTable address: "..v)
table.insert(output, v)
end
end
I am just leaving from work and can't have a deeper look at your problem right now, but the next two lines seem quite odd.
t = "00:00:00:00:00:00"
s = string.gsub( t, ":", "")
Basically you are removing all the ':' characters in the string t. Afterwards you end up with s being "000000000000". This is probably not what you want?