File: ContextPython.cpp

package info (click to toggle)
codelite 14.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 112,816 kB
  • sloc: cpp: 483,662; ansic: 150,144; php: 9,569; lex: 4,186; python: 3,417; yacc: 2,820; sh: 1,147; makefile: 52; xml: 13
file content (128 lines) | stat: -rw-r--r-- 4,536 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include "ColoursAndFontsManager.h"
#include "ContextPython.hpp"
#include "cl_editor.h"
#include "editor_config.h"
#include "lexer_configuration.h"
#include <wx/msgdlg.h>
#include <wx/regex.h>
#include <wx/tokenzr.h>
#include <wx/xrc/xmlres.h>

const wxString COMMENT_BLOCK = "\"\"\"";

ContextPython::ContextPython()
    : ContextGeneric("python")
{
}

ContextPython::ContextPython(clEditor* container)
    : ContextGeneric(container, "python")
{
    container->SetWordChars(wxT("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"));
    m_completionTriggerStrings.insert(".");
    SetName("python");
    Bind(wxEVT_MENU, &ContextPython::OnCommentSelection, this, XRCID("comment_selection"));
    Bind(wxEVT_MENU, &ContextPython::OnCommentLine, this, XRCID("comment_line"));
    m_eventsBound = true;
}

ContextPython::~ContextPython()
{
    if(m_eventsBound) {
        Unbind(wxEVT_MENU, &ContextPython::OnCommentSelection, this, XRCID("comment_selection"));
        Unbind(wxEVT_MENU, &ContextPython::OnCommentLine, this, XRCID("comment_line"));
    }
}

void ContextPython::ApplySettings()
{
    SetName("python");
    clEditor& rCtrl = GetCtrl();
    LexerConf::Ptr_t lexPtr = ColoursAndFontsManager::Get().GetLexer(GetName());
    if(lexPtr) {
        rCtrl.SetLexer(lexPtr->GetLexerId());
        for(int i = 0; i <= 4; ++i) {
            wxString keyWords = lexPtr->GetKeyWords(i);
            keyWords.Replace(wxT("\n"), wxT(" "));
            keyWords.Replace(wxT("\r"), wxT(" "));
            rCtrl.SetKeyWords(i, keyWords);
        }
    } else {
        rCtrl.SetLexer(wxSTC_LEX_NULL);
    }
    DoApplySettings(lexPtr);
}

ContextBase* ContextPython::NewInstance(clEditor* container) { return new ContextPython(container); }

void ContextPython::OnCommentSelection(wxCommandEvent& event)
{
    wxUnusedVar(event);
    GetCtrl().CommentBlockSelection(COMMENT_BLOCK, COMMENT_BLOCK);
}

void ContextPython::OnCommentLine(wxCommandEvent& event)
{
    wxUnusedVar(event);
    GetCtrl().ToggleLineComment("#", wxSTC_P_COMMENTLINE);
}

void ContextPython::AutoIndent(const wxChar& ch)
{
    ContextGeneric::AutoIndent(ch);
    clEditor& rCtrl = GetCtrl();
    int curpos = rCtrl.GetCurrentPos();
    int col = rCtrl.GetColumn(curpos);
    if(ch == '\n') {
        // if in comment block, check if we are on top of a function
        // if we are, prepare a comment block
        int curline = rCtrl.LineFromPos(curpos);
        int nPrevline = curline - 1;
        wxString prevline = rCtrl.GetLine(nPrevline);
        prevline.Trim().Trim(false);
        if(prevline == COMMENT_BLOCK) {
            // Check if the next line is a function definition
            curline++;
            int nextLinePos = rCtrl.PositionFromLine(curline);
            if(nextLinePos != wxNOT_FOUND) {
                wxString defline = rCtrl.GetLine(curline);
                static wxRegEx reDef("def[ \t]+[a-z0-9_]+[ \t]*(\\(.*?\\))[ \t]*\\:", wxRE_ADVANCED | wxRE_ICASE);
                if(reDef.IsValid() && reDef.Matches(defline)) {
                    int caretPos = curpos;
                    wxString signature = reDef.GetMatch(defline, 1);
                    signature = signature.AfterFirst('(').BeforeLast(')');
                    wxArrayString params = ::wxStringTokenize(signature, ",", wxTOKEN_STRTOK);
                    wxString doc;
                    wxString NEWLINE = rCtrl.GetEolString();
                    wxString indent(rCtrl.GetUseTabs() ? '\t' : ' ', col);
                    if(params.empty()) {
                        doc << indent << NEWLINE;
                        doc << indent << COMMENT_BLOCK;
                    } else {
                        doc << indent << NEWLINE;
                        doc << indent << "Args:" << NEWLINE;
                        for(wxString& param : params) {
                            param.Trim().Trim(false);
                            doc << indent << "    " << param << ":" << NEWLINE;
                        }
                        doc << indent << COMMENT_BLOCK;
                    }
                    rCtrl.InsertText(curpos, doc);
                    rCtrl.SetCaretAt(caretPos);
                }
            }
        }
    }
}

bool ContextPython::IsComment(int pos) const
{
    int style = GetCtrl().GetStyleAtPos(pos);
    return style == wxSTC_P_COMMENTLINE || style == wxSTC_P_COMMENTBLOCK;
}

bool ContextPython::IsCommentBlock(int pos) const
{
    int style = GetCtrl().GetStyleAtPos(pos);
    return style == wxSTC_P_COMMENTBLOCK;
}