import re
regex = re.compile(r"""
(?x)^
(?<StatementDesc>(?:
(?:
[\/\/].+(?=\n)\n)*
)*
)
(?:
(?:
# Begin Function Declaration
func[[:space:]]+
# Datatype Method?
(?:
\(
(?<funcRecvrVar>[a-zA-Z_]+)
[[:space:]]+
(?<funcRecvrTypePointerChar>\*?)
(?<funcRecvrType>[^[[:space:]\)]+)
(?<funcRecvrErr>.*?(?=[\)]))
\)
)?
[[:space:]]*
# Function Name
(?<funcName>[a-zA-Z]+)
[[:space:]]*
# Parameters
\((?<funcParamBody>
# <funcParam> is optional
(?<funcParam>
(?<funcParam1>
(?<funcParam1Name>
[A-Za-z_\d]+
(?:
[[:space:]]+
(?<funcParam1Type>
[A-Za-z_\d]+
[[:space:]]*
)?
|
[[:space:]]*
)?
)
)
# Next Parameter recursion
(?:
# Check if comma
(?=,)[,]
[[:space:]]*
(?<funcParam2>
(?<funcParam2Name>
[A-Za-z_\d]+
(?:
[[:space:]]+
(?<funcParam2Type>
[A-Za-z_\d]+
[[:space:]]*
)?
|
[[:space:]]*
)?
)
)
# Next Parameter recursion
(?:
# Check if comma
(?=,)[,]
[[:space:]]*
(?<funcParam3>
(?<funcParam3Name>
[A-Za-z_\d]+
(?:
[[:space:]]+
(?<funcParam3Type>
[A-Za-z_\d]+
[[:space:]]*
)?
|
[[:space:]]*
)?
)
)
)?
)?
(?<funcParamRest>[^\)]*)
)?
)\)
[[:space:]]*
# Return Value
(?:
# Return inside parens
(?:[\(]
(?<funcReturn1>[^\),[:space:]]+)
(?:
[[:space:]]*[,][[:space:]]*
(?<funcReturn2>[^\),[:space:]]+)
(?:
[[:space:]]*[,][[:space:]]*
(?<funcReturn3>[^\),[:space:]]+)
)?
)?
[\)]
)
|
# Single Return Outside Parens
(?<funcReturnSingle>[^\{[:space:]]+)
|
)?
[[:space:]]*
[[:space:]]*
)
# Remove Non-relevant lines
(?<removed>
(?:
# At new line, check if its blank || begins with spaces or not `func`
(?=
(?:
$
|
[[:space:]\t].+\n
|
(?!\/\/|func)
)
)
.+\n+(?=(?![\/]|func))
)+
)?
)
""", flags=re.MULTILINE | re.IGNORECASE | re.VERBOSE)
test_str = ("//test \n"
"func (m *Messenger) LetterPrompt(param1 type1, param2 type2) {\n\n"
"}\n\n"
"// TermMessage sends a message to the user in the terminal. This usually occurs before\n"
"// micro has been fully initialized -- ie if there is an error in the syntax highlighting\n"
"// regular expressions\n"
"// The function must be called when the screen is not initialized\n"
"// This will write the message, and wait for the user\n"
"// to press and key to continue\n"
"func TermMessage(msg ...interface{}) {\n"
" screenWasNil := screen == nil\n"
" if !screenWasNil {\n"
" screen.Fini()\n"
" screen = nil\n"
" }\n\n"
" fmt.Println(msg...)\n"
" fmt.Print(\"\\nPress enter to continue\")\n\n"
" reader := bufio.NewReader(os.Stdin)\n"
" reader.ReadString('\\n')\n\n"
" if !screenWasNil {\n"
" InitScreen()\n"
" }\n"
"}\n\n"
"// TermError sends an error to the user in the terminal. Like TermMessage except formatted\n"
"// as an error\n"
"func TermError(filename string, lineNum int, err string) *Buffer {\n"
" TermMessage(filename + \", \" + strconv.Itoa(lineNum) + \": \" + err)\n"
"}\n\n"
"// Messenger is an object that makes it easy to send messages to the user\n"
"// and get input from the user\n"
"type Messenger struct {\n"
" log *Buffer\n"
" // Are we currently prompting the user?\n"
" hasPrompt bool\n"
" // Is there a message to print\n"
" hasMessage bool\n\n"
" // Message to print\n"
" message string\n"
" // The user's response to a prompt\n"
" response string\n"
" // style to use when drawing the message\n"
" style tcell.Style\n\n"
" // We have to keep track of the cursor for prompting\n"
" cursorx int\n\n"
" // This map stores the history for all the different kinds of uses Prompt has\n"
" // It's a map of history type -> history array\n"
" history map[string][]string\n"
" historyNum int\n\n"
" // Is the current message a message from the gutter\n"
" gutterMessage bool\n"
"}\n\n"
"// AddLog sends a message to the log view\n"
"func (m *Messenger) AddLog(msg ...interface{}) {\n"
" logMessage := fmt.Sprint(msg...)\n"
" buffer := m.getBuffer()\n"
" buffer.insert(buffer.End(), []byte(logMessage+\"\\n\"))\n"
" buffer.Cursor.Loc = buffer.End()\n"
" buffer.Cursor.Relocate()\n"
"}\n\n"
"func (m *Messenger) getBuffer() *Buffer {\n"
" if m.log == nil {\n"
" m.log = NewBufferFromString(\"\", \"\")\n"
" m.log.name = \"Log\"\n"
" }\n"
" return m.log\n"
"}\n\n"
"// Message sends a message to the user\n"
"func (m *Messenger) Message(msg ...interface{}) {\n"
" displayMessage := fmt.Sprint(msg...)\n"
" // only display a new message if there isn't an active prompt\n"
" // this is to prevent overwriting an existing prompt to the user\n"
" if m.hasPrompt == false {\n"
" // if there is no active prompt then style and display the message as normal\n"
" m.message = displayMessage\n\n"
" m.style = defStyle\n\n"
" if _, ok := colorscheme[\"message\"]; ok {\n"
" m.style = colorscheme[\"message\"]\n"
" }\n\n"
" m.hasMessage = true\n"
" }\n"
" // add the message to the log regardless of active prompts\n"
" m.AddLog(displayMessage)\n"
"}\n\n"
"// Error sends an error message to the user\n"
"func (m *Messenger) Error(msg ...interface{}) {\n"
" buf := new(bytes.Buffer)\n"
" fmt.Fprint(buf, msg...)\n\n"
" // only display a new message if there isn't an active prompt\n"
" // this is to prevent overwriting an existing prompt to the user\n"
" if m.hasPrompt == false {\n"
" // if there is no active prompt then style and display the message as normal\n"
" m.message = buf.String()\n"
" m.style = defStyle.\n"
" Foreground(tcell.ColorBlack).\n"
" Background(tcell.ColorMaroon)\n\n"
" if _, ok := colorscheme[\"error-message\"]; ok {\n"
" m.style = colorscheme[\"error-message\"]\n"
" }\n"
" m.hasMessage = true\n"
" }\n"
" // add the message to the log regardless of active prompts\n"
" m.AddLog(buf.String())\n"
"}\n\n"
"func (m *Messenger) PromptText(msg ...interface{}) {\n"
" displayMessage := fmt.Sprint(msg...)\n"
"}\n\n"
"// YesNoPrompt asks the user a yes or no question (waits for y or n) and returns the result\n"
"func (m *Messenger) YesNoPrompt(prompt string) (bool, bool) {\n"
" m.hasPrompt = true\n"
" m.PromptText(prompt)\n\n"
" _, h := screen.Size()\n"
" for {\n"
" m.Clear()\n"
" m.Display()\n"
" screen.ShowCursor(Count(m.message), h-1)\n"
" screen.Show()\n"
" event := <-events\n\n"
" switch e := event.(type) {\n"
" case *tcell.EventKey:\n"
" switch e.Key() {\n"
" case tcell.KeyRune:\n"
" if e.Rune() == 'y' || e.Rune() == 'Y' {\n"
" m.AddLog(\"\\t--> y\")\n"
" m.hasPrompt = false\n"
" return true, false\n"
" } else if e.Rune() == 'n' || e.Rune() == 'N' {\n"
" m.AddLog(\"\\t--> n\")\n"
" m.hasPrompt = false\n"
" return false, false\n"
" }\n"
" case tcell.KeyCtrlC, tcell.KeyCtrlQ, tcell.KeyEscape:\n"
" m.AddLog(\"\\t--> (cancel)\")\n"
" m.Clear()\n"
" m.Reset()\n"
" m.hasPrompt = false\n"
" return false, true\n"
" }\n"
" }\n"
" }\n"
"}\n\n"
"// LetterPrompt gives the user a prompt and waits for a one letter response\n"
"func (m *Messenger) LetterPrompt(prompt string, responses ...rune) (rune, bool) {\n"
" m.hasPrompt = true\n"
" m.PromptText(prompt)\n\n"
" _, h := screen.Size()\n"
" for {\n"
" m.Clear()\n"
" m.Display()\n"
" screen.ShowCursor(Count(m.message), h-1)\n"
" screen.Show()\n"
" event := <-events\n\n"
" switch e := event.(type) {\n"
" case *tcell.EventKey:\n"
" switch e.Key() {\n"
" case tcell.KeyRune:\n"
" for _, r := range responses {\n"
" if e.Rune() == r {\n"
" m.AddLog(\"\\t--> \" + string(r))\n"
" m.Clear()\n"
" m.Reset()\n"
" m.hasPrompt = false\n"
" return r, false\n"
" }\n"
" }\n"
" case tcell.KeyCtrlC, tcell.KeyCtrlQ, tcell.KeyEscape:\n"
" m.AddLog(\"\\t--> (cancel)\")\n"
" m.Clear()\n"
" m.Reset()\n"
" m.hasPrompt = false\n"
" return ' ', true\n"
" }\n"
" }\n"
" }\n"
"}\n\n"
"// Completion represents a type of completion\n"
"type Completion int\n\n"
"const (\n"
" NoCompletion Completion = iota\n"
" FileCompletion\n"
" CommandCompletion\n"
" HelpCompletion\n"
" OptionCompletion\n"
" PluginCmdCompletion\n"
" PluginNameCompletion\n"
" OptionValueCompletion\n"
")\n\n"
"// Prompt sends the user a message and waits for a response to be typed in\n"
"// This function blocks the main loop while waiting for input\n"
"func (m *Messenger) Prompt(prompt, placeholder, historyType string, completionTypes ...Completion) (string, bool) {\n"
" m.hasPrompt = true\n"
" m.PromptText(prompt)\n"
" if _, ok := m.history[historyType]; !ok {\n"
" m.history[historyType] = []string{\"\"}\n"
" } else {\n"
" m.history[historyType] = append(m.history[historyType], \"\")\n"
" }\n"
" m.historyNum = len(m.history[historyType]) - 1\n\n"
" response, canceled := placeholder, true\n"
" m.response = response\n"
" m.cursorx = Count(placeholder)\n\n"
" RedrawAll()\n"
" for m.hasPrompt {\n"
" var suggestions []string\n"
" m.Clear()\n\n"
" event := <-events\n\n"
" switch e := event.(type) {\n"
" case *tcell.EventResize:\n"
" for _, t := range tabs {\n"
" t.Resize()\n"
" }\n"
" RedrawAll()\n"
" case *tcell.EventKey:\n"
" switch e.Key() {\n"
" case tcell.KeyCtrlQ, tcell.KeyCtrlC, tcell.KeyEscape:\n"
" // Cancel\n"
" m.AddLog(\"\\t--> (cancel)\")\n"
" m.hasPrompt = false\n"
" case tcell.KeyEnter:\n"
" // User is done entering their response\n"
" m.AddLog(\"\\t--> \" + m.response)\n"
" m.hasPrompt = false\n"
" response, canceled = m.response, false\n"
" m.history[historyType][len(m.history[historyType])-1] = response\n"
" case tcell.KeyTab:\n"
" args, err := shellwords.Split(m.response)\n"
" if err != nil {\n"
" break\n"
" }\n"
" currentArg := \"\"\n"
" currentArgNum := 0\n"
" if len(args) > 0 {\n"
" currentArgNum = len(args) - 1\n"
" currentArg = args[currentArgNum]\n"
" }\n"
" var completionType Completion\n\n"
" if completionTypes[0] == CommandCompletion && currentArgNum > 0 {\n"
" if command, ok := commands[args[0]]; ok {\n"
" completionTypes = append([]Completion{CommandCompletion}, command.completions...)\n"
" }\n"
" }\n\n"
" if currentArgNum >= len(completionTypes) {\n"
" completionType = completionTypes[len(completionTypes)-1]\n"
" } else {\n"
" completionType = completionTypes[currentArgNum]\n"
" }\n\n"
" var chosen string\n"
" if completionType == FileCompletion {\n"
" chosen, suggestions = FileComplete(currentArg)\n"
" } else if completionType == CommandCompletion {\n"
" chosen, suggestions = CommandComplete(currentArg)\n"
" } else if completionType == HelpCompletion {\n"
" chosen, suggestions = HelpComplete(currentArg)\n"
" } else if completionType == OptionCompletion {\n"
" chosen, suggestions = OptionComplete(currentArg)\n"
" } else if completionType == OptionValueCompletion {\n"
" if currentArgNum-1 > 0 {\n"
" chosen, suggestions = OptionValueComplete(args[currentArgNum-1], currentArg)\n"
" }\n"
" } else if completionType == PluginCmdCompletion {\n"
" chosen, suggestions = PluginCmdComplete(currentArg)\n"
" } else if completionType == PluginNameCompletion {\n"
" chosen, suggestions = PluginNameComplete(currentArg)\n"
" } else if completionType < NoCompletion {\n"
" chosen, suggestions = PluginComplete(completionType, currentArg)\n"
" }\n\n"
" if len(suggestions) > 1 {\n"
" chosen = chosen + CommonSubstring(suggestions...)\n"
" }\n\n"
" if len(suggestions) != 0 && chosen != \"\" {\n"
" m.response = shellwords.Join(append(args[:len(args)-1], chosen)...)\n"
" m.cursorx = Count(m.response)\n"
" }\n"
" }\n"
" }\n\n"
" m.HandleEvent(event, m.history[historyType])\n\n"
" m.Clear()\n"
" for _, v := range tabs[curTab].Views {\n"
" v.Display()\n"
" }\n"
" DisplayTabs()\n"
" m.Display()\n"
" if len(suggestions) > 1 {\n"
" m.DisplaySuggestions(suggestions)\n"
" }\n"
" screen.Show()\n"
" }\n\n"
" m.Clear()\n"
" m.Reset()\n"
" return response, canceled\n"
"}\n\n"
"// UpHistory fetches the previous item in the history\n"
"func (m *Messenger) UpHistory(history []string) {\n"
" if m.historyNum > 0 {\n"
" m.historyNum--\n"
" m.response = history[m.historyNum]\n"
" m.cursorx = Count(m.response)\n"
" }\n"
"}\n\n"
"// DownHistory fetches the next item in the history\n"
"func (m *Messenger) DownHistory(history []string) {\n"
" if m.historyNum < len(history)-1 {\n"
" m.historyNum++\n"
" m.response = history[m.historyNum]\n"
" m.cursorx = Count(m.response)\n"
" }\n"
"}\n\n"
"// CursorLeft moves the cursor one character left\n"
"func (m *Messenger) CursorLeft() {\n"
" if m.cursorx > 0 {\n"
" m.cursorx--\n"
" }\n"
"}\n\n"
"// CursorRight moves the cursor one character right\n"
"func (m *Messenger) CursorRight() {\n"
" if m.cursorx < Count(m.response) {\n"
" m.cursorx++\n"
" }\n"
"}\n\n"
"// Start moves the cursor to the start of the line\n"
"func (m *Messenger) Start() {\n"
" m.cursorx = 0\n"
"}\n\n"
"// End moves the cursor to the end of the line\n"
"func (m *Messenger) End() {\n"
" m.cursorx = Count(m.response)\n"
"}\n\n"
"// Backspace deletes one character\n"
"func (m *Messenger) Backspace() {\n"
" if m.cursorx > 0 {\n"
" m.response = string([]rune(m.response)[:m.cursorx-1]) + string([]rune(m.response)[m.cursorx:])\n"
" m.cursorx--\n"
" }\n"
"}\n\n"
"// Paste pastes the clipboard\n"
"func (m *Messenger) Paste() {\n"
" clip, _ := clipboard.ReadAll(\"clipboard\")\n"
" m.response = Insert(m.response, m.cursorx, clip)\n"
" m.cursorx += Count(clip)\n"
"}\n\n"
"// WordLeft moves the cursor one word to the left\n"
"func (m *Messenger) WordLeft() {\n"
" response := []rune(m.response)\n"
" m.CursorLeft()\n"
" if m.cursorx <= 0 {\n"
" return\n"
" }\n"
" for IsWhitespace(response[m.cursorx]) {\n"
" if m.cursorx <= 0 {\n"
" return\n"
" }\n"
" m.CursorLeft()\n"
" }\n"
" m.CursorLeft()\n"
" for IsWordChar(string(response[m.cursorx])) {\n"
" if m.cursorx <= 0 {\n"
" return\n"
" }\n"
" m.CursorLeft()\n"
" }\n"
" m.CursorRight()\n"
"}\n\n"
"// WordRight moves the cursor one word to the right\n"
"func (m *Messenger) WordRight() {\n"
" response := []rune(m.response)\n"
" if m.cursorx >= len(response) {\n"
" return\n"
" }\n"
" for IsWhitespace(response[m.cursorx]) {\n"
" m.CursorRight()\n"
" if m.cursorx >= len(response) {\n"
" m.CursorRight()\n"
" return\n"
" }\n"
" }\n"
" m.CursorRight()\n"
" if m.cursorx >= len(response) {\n"
" return\n"
" }\n"
" for IsWordChar(string(response[m.cursorx])) {\n"
" m.CursorRight()\n"
" if m.cursorx >= len(response) {\n"
" return\n"
" }\n"
" }\n"
"}\n\n"
"// DeleteWordLeft deletes one word to the left\n"
"func (m *Messenger) DeleteWordLeft() {\n"
" m.WordLeft()\n"
" m.response = string([]rune(m.response)[:m.cursorx])\n"
"}\n\n"
"// HandleEvent handles an event for the prompter\n"
"func (m *Messenger) HandleEvent(event tcell.Event, history []string) {\n"
" switch e := event.(type) {\n"
" case *tcell.EventKey:\n"
" switch e.Key() {\n"
" case tcell.KeyCtrlA:\n"
" m.Start()\n"
" case tcell.KeyCtrlE:\n"
" m.End()\n"
" case tcell.KeyUp:\n"
" m.UpHistory(history)\n"
" case tcell.KeyDown:\n"
" m.DownHistory(history)\n"
" case tcell.KeyLeft:\n"
" if e.Modifiers() == tcell.ModCtrl {\n"
" m.Start()\n"
" } else if e.Modifiers() == tcell.ModAlt || e.Modifiers() == tcell.ModMeta {\n"
" m.WordLeft()\n"
" } else {\n"
" m.CursorLeft()\n"
" }\n"
" case tcell.KeyRight:\n"
" if e.Modifiers() == tcell.ModCtrl {\n"
" m.End()\n"
" } else if e.Modifiers() == tcell.ModAlt || e.Modifiers() == tcell.ModMeta {\n"
" m.WordRight()\n"
" } else {\n"
" m.CursorRight()\n"
" }\n"
" case tcell.KeyBackspace2, tcell.KeyBackspace:\n"
" if e.Modifiers() == tcell.ModCtrl || e.Modifiers() == tcell.ModAlt || e.Modifiers() == tcell.ModMeta {\n"
" m.DeleteWordLeft()\n"
" } else {\n"
" m.Backspace()\n"
" }\n"
" case tcell.KeyCtrlW:\n"
" m.DeleteWordLeft()\n"
" case tcell.KeyCtrlV:\n"
" m.Paste()\n"
" case tcell.KeyCtrlF:\n"
" m.WordRight()\n"
" case tcell.KeyCtrlB:\n"
" m.WordLeft()\n"
" case tcell.KeyRune:\n"
" m.response = Insert(m.response, m.cursorx, string(e.Rune()))\n"
" m.cursorx++\n"
" }\n"
" history[m.historyNum] = m.response\n\n"
" case *tcell.EventPaste:\n"
" clip := e.Text()\n"
" m.response = Insert(m.response, m.cursorx, clip)\n"
" m.cursorx += Count(clip)\n"
" case *tcell.EventMouse:\n"
" x, y := e.Position()\n"
" x -= Count(m.message)\n"
" button := e.Buttons()\n"
" _, screenH := screen.Size()\n\n"
" if y == screenH-1 {\n"
" switch button {\n"
" case tcell.Button1:\n"
" m.cursorx = x\n"
" if m.cursorx < 0 {\n"
" m.cursorx = 0\n"
" } else if m.cursorx > Count(m.response) {\n"
" m.cursorx = Count(m.response)\n"
" }\n"
" }\n"
" }\n"
" }\n"
"}\n\n"
"// Reset resets the messenger's cursor, message and response\n"
"func (m *Messenger) Reset() {\n"
" m.cursorx = 0\n"
" m.message = \"\"\n"
" m.response = \"\"\n"
"}\n\n"
"// Clear clears the line at the bottom of the editor\n"
"func (m *Messenger) Clear() {\n"
" w, h := screen.Size()\n"
" for x := 0; x < w; x++ {\n"
" screen.SetContent(x, h-1, ' ', nil, defStyle)\n"
" }\n"
"}\n\n"
"func (m *Messenger) DisplaySuggestions(suggestions []string) {\n"
" w, screenH := screen.Size()\n\n"
" y := screenH - 2\n\n"
" statusLineStyle := defStyle.Reverse(true)\n"
" if style, ok := colorscheme[\"statusline\"]; ok {\n"
" statusLineStyle = style\n"
" }\n\n"
" for x := 0; x < w; x++ {\n"
" screen.SetContent(x, y, ' ', nil, statusLineStyle)\n"
" }\n\n"
" x := 0\n"
" for _, suggestion := range suggestions {\n"
" for _, c := range suggestion {\n"
" screen.SetContent(x, y, c, nil, statusLineStyle)\n"
" x++\n"
" }\n"
" screen.SetContent(x, y, ' ', nil, statusLineStyle)\n"
" x++\n"
" }\n"
"}\n\n"
"// Display displays messages or prompts\n"
"func (m *Messenger) Display() {\n"
" _, h := screen.Size()\n"
" if m.hasMessage {\n"
" if m.hasPrompt || globalSettings[\"infobar\"].(bool) {\n"
" runes := []rune(m.message + m.response)\n"
" posx := 0\n"
" for x := 0; x < len(runes); x++ {\n"
" screen.SetContent(posx, h-1, runes[x], nil, m.style)\n"
" posx += runewidth.RuneWidth(runes[x])\n"
" }\n"
" }\n"
" }\n\n"
" if m.hasPrompt {\n"
" screen.ShowCursor(Count(m.message)+m.cursorx, h-1)\n"
" screen.Show()\n"
" }\n"
"}\n\n"
"// LoadHistory attempts to load user history from configDir/buffers/history\n"
"// into the history map\n"
"// The savehistory option must be on\n"
"func (m *Messenger) LoadHistory() {\n"
" if GetGlobalOption(\"savehistory\").(bool) {\n"
" file, err := os.Open(configDir + \"/buffers/history\")\n"
" defer file.Close()\n"
" var decodedMap map[string][]string\n"
" if err == nil {\n"
" decoder := gob.NewDecoder(file)\n"
" err = decoder.Decode(&decodedMap)\n\n"
" if err != nil {\n"
" m.Error(\"Error loading history:\", err)\n"
" return\n"
" }\n"
" }\n\n"
" if decodedMap != nil {\n"
" m.history = decodedMap\n"
" } else {\n"
" m.history = make(map[string][]string)\n"
" }\n"
" } else {\n"
" m.history = make(map[string][]string)\n"
" }\n"
"}\n\n"
"// SaveHistory saves the user's command history to configDir/buffers/history\n"
"// only if the savehistory option is on\n"
"func (m *Messenger) SaveHistory() {\n"
" if GetGlobalOption(\"savehistory\").(bool) {\n"
" // Don't save history past 100\n"
" for k, v := range m.history {\n"
" if len(v) > 100 {\n"
" m.history[k] = v[len(m.history[k])-100:]\n"
" }\n"
" }\n\n"
" file, err := os.Create(configDir + \"/buffers/history\")\n"
" defer file.Close()\n"
" if err == nil {\n"
" encoder := gob.NewEncoder(file)\n\n"
" err = encoder.Encode(m.history)\n"
" if err != nil {\n"
" m.Error(\"Error saving history:\", err)\n"
" return\n"
" }\n"
" }\n"
" }\n"
"}\n\n"
"// A GutterMessage is a message displayed on the side of the editor\n"
"type GutterMessage struct {\n"
" lineNum int\n"
" msg string\n"
" kind int\n"
"}\n\n"
"// These are the different types of messages\n"
"const (\n"
" // GutterInfo represents a simple info message\n"
" GutterInfo = iota\n"
" // GutterWarning represents a compiler warning\n"
" GutterWarning\n"
" // GutterError represents a compiler error\n"
" GutterError\n"
")\n")
subst = ""
result = regex.sub(subst, test_str)
if result:
print(result)
Please keep in mind that these code samples are automatically generated and are not guaranteed to work. If you find any syntax errors, feel free to submit a bug report. For a full regex reference for Python, please visit: https://docs.python.org/3/library/re.html