Generating a specified number of sub-snippets using Ultisnips in vim - vim

I currently have a tex.snippets file to hold snippets which make writing homework in LaTeX easier. For example, I have a snippet '2problem' of the form:
snippet 2problem
\begin{homeworkProblem}
\begin{enumerate}
\item[] $1
$2
\item[] $3
$4
\end{enumerate}
\end{homeworkProblem}
endsnippet
This gives me an easy way of starting 2-part problems. Is there a way, however, of making a snippet that outputs n-part problems? Right now I have separate snippets for separate number of problems, which is quite tedious.

I know, this is not an ultisnip solution, just in case : mu-template supports loops and recursion in snippets. That how I generate a switch-case construct from an enum definition in C and C++. It's kind of cumbersome to define, but it works well.

Use the snippet definition as:
post_jump "dynamicsnippet(snip)"
snippet '(\d+)problem' rb
\begin{homeworkProblem}
\begin{enumerate}
`!p snip.rv=create_partprob(int(match.group(1)))`
\end{enumerate}
\end{homeworkProblem}
endsnippet
Attach this piece of code at the end of the desired snippets file.(Probably something like tex.snippets)
global !p
def dynamicsnippet(snip):
# Create anonymous snippet body
anon_snippet_body = ""
# Get start and end line number of expanded snippet
start = snip.snippet_start[0]
end = snip.snippet_end[0]
# Append current line into anonymous snippet
for i in range(start, end + 1):
anon_snippet_body += snip.buffer[i]
anon_snippet_body += "" if i == end else "\n"
# Delete expanded snippet line till second to last line
for i in range(start, end):
del snip.buffer[start]
# Empty last expanded snippet line while preserving the line
snip.buffer[start] = ''
# Expand anonymous snippet
snip.expand_anon(anon_snippet_body)
def create_partprob(n):
out=""
placeholder=1
for _ in range(0,n):
out+=24*" "+"\\item[] $"+f"{placeholder}\\\\\\\\\n"
placeholder+=1
out+=24*" "+" $"+f"{placeholder}\\\\\\\\\n"
placeholder+=1
out=out[:-1]
return out
endglobal
It worked in my editor and Ultisnips, hope it works in yours as well.
Goodluck!
Edit: Use the stack specifically made for vim and vi related questions for such questions. You can find the site here.

Related

Strip comments from Julia code to produce a minified file

I have a Julia code that I want to put in somewhere else. The problem is that I need to remove all comments/unnecessary stuff from the code. How can I do this in Julia?
Example:
"""
example(hello::String, world::Int)::Nothing
Prints something.
"""
function example(hello::String, world::Int)::Nothing
# Hey!
println("$hello = $world"); # Print something
end
I want to open this file in Julia and remove all comments and save this new file:
function example(hello::String, world::Int)::Nothing
println("$hello = $world");
end
Or at least this (keeping inline comments is ok for me, as it would be hard to catch cases like print("#")):
function example(hello::String, world::Int)::Nothing
println("$hello = $world"); # Print something
end
For one-line comments, I can split the code by lines, and filter the lines that startswith # after strip(). But I have no idea about multi line comments.

Why does error 'unexpected character after line continuation character' appear here?

Does someone know what is wrong with this section of my code as it seems to cause errors. I'm new to programming so I'm not completely sure what's wrong.
menu = "Be Lenny's Friend?\n"
1. Yes\n\
2. No\n\
answer = int(input(menu))
if answer == 1:
print(" ( ͡° ͜ʖ ͡°): Yayyyy! We are going to be friends!")
elif answer == 2:
reason = input(" ( ͡° ʖ̯ ͡°): Why do you not want to be my friend :(")
Error message:
'unexpected character after line continuation character'
Here you have set the variable as a tuple of a string and... well that’s where things get confusing.
The backslash is a like continuation symbol as in you can then break the line and continue on and it would count as the same line. However what the interpreter sees is n: which makes no sense. That is what it is complaining about.
If you wanted to add a new line to the string itself, you could add the \n at the end of the string.
However, also note that if you printed the string using print in the vanilla form without any other arguments than the Adrianne itself, it will append a new line automatically. So if you do add the \n, it may still not be what you want when you print it out. Parameter can of course be changed in the print function to take care of that.
I'm not sure what you are trying to archive with ,\n\: at the end of the line, but this line of code will remove the syntax error:
menu = "Be Lenny's Friend?"
If you want to archive a new line after the string you need to move "\n" into the string like this:
menu = "Be Lenny's Friend?\n"
Edit:
This should work for you:
menu = "Be Lenny's Friend?\n\t1. Yes\n\t2. No\n"
answer = int(input(menu))
if answer == 1: print(" ( ͡° ͜ʖ ͡°): Yayyyy! We are going to be friends!")
elif answer == 2: reason = input(" ( ͡° ʖ̯ ͡°): Why do you not want to be my friend :(\n")

An Elegant Solution to Python's Multiline String?

I was trying to log a completion of a scheduled event I set to run on Django. I was trying my very best to make my code look presentable, So instead of putting the string into a single line, I have used a multiline string to output to the logger within a Command Management class method. The example as code shown:
# the usual imports...
# ....
import textwrap
logger = logging.getLogger(__name__)
class Command(BaseCommand):
def handle(self, *args, **kwargs):
# some codes here
# ....
final_statement = f'''\
this is the final statements \
with multiline string to have \
a neater code.'''
dedented_text = textwrap.dedent(final_statment)
logger.info(dedent.replace(' ',''))
I have tried a few methods I found, however, most quick and easy methods still left a big chunk of spaces on the terminal. As shown here:
this is the final statement with multiline string to have a neater code.
So I have come up with a creative solution to solve my problem. By using.
dedent.replace(' ','')
Making sure to replace two spaces with no space in order not to get rid of the normal spaces between words. Which finally produced:
this is the final statement with multiline string to have a neater code.
Is this an elegant solution or did I missed something on the internet?
You could use regex to simply remove all white space after a newline. Additionally, wrapping it into a function leads to less repetitive code, so let's do that.
import re
def single_line(string):
return re.sub("\n\s+", "", string)
final_statement = single_line(f'''
this is the final statements
with multiline string to have
a neater code.''')
print(final_statement)
Alternatively, if you wish to avoid this particular problem (and don't mine the developmental overhead), you could store them inside a file, like JSON so you can quickly edit prompts while keeping your code clean.
Thanks to Neil's suggestion, I have come out with a more elegant solution. By creating a function to replace the two spaces with none.
def single_line(string):
return string.replace(' ','')
final_statement = '''\
this is a much neater
final statement
to present my code
'''
print(single_line(final_statement)
As improvised from Neil's solution, I have cut down the regex import. That's one line less of code!
Also, making it a function improves on readability as the whole print statement just read like English. "Print single line final statement"
Any better idea?
The issue with both Neil’s and Wong Siwei’s answers is they don’t work if your multiline string contains lines more indented than others:
my_string = """\
this is my
string and
it has various
identation
levels"""
What you want in the case above is to remove the two-spaces indentation, not every space at the beginning of a line.
The solution below should work in all cases:
import re
def dedent(s):
indent_level = None
for m in re.finditer(r"^ +", s):
line_indent_level = len(m.group())
if indent_level is None or indent_level > line_indent_level:
indent_level = line_indent_level
if not indent_level:
return s
return re.sub(r"(?:^|\n) {%s}" % indent_level, "", s)
It first scans the whole string to find the lowest indentation level then uses that information to dedent all lines of it.
If you only care about making your code easier to read, you may instead use C-like strings "concatenation":
my_string = (
"this is my string"
" and I write it on"
" multiple lines"
)
print(repr(my_string))
# => "this is my string and I write it on multiple lines"
You may also want to make it explicit with +s:
my_string = "this is my string" + \
" and I write it on" + \
" multiple lines"

How to add the line number at the beginning of each line in a file

So.. I need to read a file and add the line number at the beginning of each line. Just as the title. How do you do it?
For example, if the content of the file was:
This
is
a
simple
test
file
These 6 lines, I should turn it into
1. This
2. is
3. a
4. simple
5. test
6. file
Keep the original content, but just adding the line number at the beginning.
My code looks like this so far:
def add_numbers(filename):
f = open(filename, "w+")
line_number = 1
for line in f.readlines():
number_added = str(line_number) + '. ' + f.readline(line)
line_number += 1
return number_added
But it doesn't really show anything as the result. I have no clues how to do it. Any help?
A few problems I see in your code:
You indentation is not correct. Everything below the def add_numbers(): should be indented one level.
It is good practice to close a file handle at the end of your method.
A similar question to yours was asked here. Looking at the various solutions posted there, using fileinput seems like your best bet because it allows you to edit your file in-place.
import fileinput
def add_numbers(filename):
line_number = 1
for line in fileinput.input(filename, inplace=True):
print("{}. {}".format(line_number, line))
line_number += 1
Also note that I use format to combine two strings instead adding them together, because this handles different variable types more easily. A good explanation of the use of format can be found here.

Lua pattern to stop when end of line

I need to get help for a pattern in Lua stopping to read after a line break.
My code:
function getusers(file)
local list, close = {}
local user, value = string.match(file,"(UserName=)(.*)")
print(value)
f:close()
end
f = assert(io.open('file2.ini', "r"))
local t = f:read("*all")
getusers(t)
--file2.ini--
user=a
UserName=Tom
Password=xyz
UserName=Jane
Output of script using file2.ini:
Tom
Password=xyz
UserName=Jane
How to get the pattern to stop after it reaches the end of line?
You can use the pattern
"(UserName=)(.-)\n"
Note that besides the extra \n, the lazy modifier - is used instead of *.
As #lhf points out, make sure the file ends with a new line. I think you can append a \n to the string manually before matching.

Resources