Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[-------------------------------------------------------
- Custom markup for the documentation
- --]]-------------------------------------------------------
- local CUSTOM_MARK_ITAL = '^^_' -- italic
- local CUSTOM_MARK_BOLD = '^^*' -- bold
- local CUSTOM_MARK_LINK = '^^$' -- link description start
- local CUSTOM_MARK_LINZ = '$^^' -- link description end
- local CUSTOM_MARK_LINA = '^^&' -- link URL start
- local CUSTOM_MARK_LINT = '&^^' -- link URL end
- local CUSTOM_MARK_HEAD = '^^#' -- header
- local CUSTOM_MARK_CODE = '^^`' -- code
- local CUSTOM_MARK_BOXD = '^^|' -- highlight
- local CUSTOM_MARK_MARK = ' ' -- separator
- local markup = {
- [CUSTOM_MARK_BOXD] = {fg={127,0,127}, b=true},
- [CUSTOM_MARK_CODE] = {fg={127,127,127}, fs=10},
- [CUSTOM_MARK_HEAD] = {fn="Lucida Console", b=true},
- [CUSTOM_MARK_LINK] = {u=true, hs={32,32,127}},
- [CUSTOM_MARK_BOLD] = {b=true, fg={0,0,0}},
- [CUSTOM_MARK_ITAL] = {i=true},
- }
- local q = EscapeMagic
- local CUSTOM_MARK_PTRN = '' -- combination of all markup marks that can start styling
- for key in pairs(markup) do
- if key ~= CUSTOM_MARK_MARK then CUSTOM_MARK_PTRN = CUSTOM_MARK_PTRN .. q(key) end
- end
- local function ismarkup (tx)
- local start = 1
- local marksep = "[%s!%?%.,;:%(%)]"
- while true do
- -- find a separator first
- local st,_,sep,more = string.find(tx, "(["..CUSTOM_MARK_PTRN.."])(.)", start)
- if not st then return end
- -- check if this is a first character of a multi-character separator
- if not markup[sep] then sep = sep .. (more or '') end
- local s,e,cap
- local qsep = q(sep)
- local nonsep = ("[^%s]"):format(qsep)
- local nonspace = ("[^%s]"):format(qsep.."%s")
- if sep == CUSTOM_MARK_HEAD then
- -- always search from the start of the line
- -- [%w%p] set is needed to avoid continuing this markup to the next line
- s,e,cap = string.find(tx,"^("..q(CUSTOM_MARK_HEAD)..".+[%w%p])")
- elseif sep == CUSTOM_MARK_LINK then
- -- allow everything based on balanced link separators
- s,e,cap = string.find(tx,
- "^(%b"..CUSTOM_MARK_LINK..CUSTOM_MARK_LINZ
- .."%b"..CUSTOM_MARK_LINA..CUSTOM_MARK_LINT..")", st)
- elseif markup[sep] then
- -- try 2+ characters between separators first
- -- if not found, try a single character
- s,e,cap = string.find(tx,"^("..qsep..nonspace..nonsep.."-"..nonspace..qsep..")", st)
- if not s then s,e,cap = string.find(tx,"^("..qsep..nonspace..qsep..")", st) end
- end
- if s and -- selected markup is surrounded by spaces or punctuation marks
- (s == 1 or tx:sub(s-1, s-1):match(marksep)) and
- (e == #tx or tx:sub(e+1, e+1):match(marksep))
- then return s,e,cap,sep end
- start = st+1
- end
- end
- local custom_style = function (editor, lines, linee)
- local lines = lines or 0
- if (lines < 0) then return end
- -- if the current spec doesn't have any comments, nothing to style
- if not next(editor.spec.iscomment) then return end
- -- always style to the end as there may be comments that need re-styling
- -- technically, this should be GetLineCount()-1, but we want to style
- -- beyond the last line to make sure it is styled correctly
- local linec = editor:GetLineCount()
- local linee = linee or linec
- local linecomment = editor.spec.linecomment
- local iscomment = {}
- for i,v in pairs(editor.spec.iscomment) do
- iscomment[i] = v
- end
- local es = editor:GetEndStyled()
- local needfix = false
- for line=lines,linee do
- local tx = editor:GetLine(line)
- local ls = editor:PositionFromLine(line)
- local from = 1
- local off = -1
- -- doing WrapCount(line) when line == linec (which may be beyond
- -- the last line) occasionally crashes the application on OSX.
- local wrapped = line < linec and editor:WrapCount(line) or 0
- while from do
- tx = string.sub(tx,from)
- local f,t,w,mark = ismarkup(tx)
- if (f) then
- local p = ls+f+off
- local s = bit.band(editor:GetStyleAt(p), 31)
- -- only style comments and only those that are not at the beginning
- -- of the file to avoid styling shebang (#!) lines
- -- also ignore matches for line comments (as defined in the spec)
- if iscomment[s] and p > 0 and mark ~= linecomment then
- local smark = #mark
- local emark = #mark -- assumes end mark is the same length as start mark
- if mark == CUSTOM_MARK_HEAD then
- -- grab multiple CUSTOM_MARK_HEAD if present
- local _,_,full = string.find(w,"^("..q(CUSTOM_MARK_HEAD).."+)")
- smark,emark = #full,0
- elseif mark == CUSTOM_MARK_LINK then
- local lsep = w:find(q(CUSTOM_MARK_LINZ)..q(CUSTOM_MARK_LINA))
- if lsep then emark = #w-lsep+#CUSTOM_MARK_LINT end
- end
- editor:StartStyling(p, 31)
- editor:SetStyling(smark, markup[CUSTOM_MARK_MARK].st)
- editor:SetStyling(t-f+1-smark-emark, markup[mark].st or markup[CUSTOM_MARK_MARK].st)
- editor:SetStyling(emark, markup[CUSTOM_MARK_MARK].st)
- end
- off = off + t
- end
- from = t and (t+1)
- end
- -- has this line changed its wrapping because of invisible styling?
- if wrapped > 1 and editor:WrapCount(line) < wrapped then needfix = true end
- end
- editor:StartStyling(es, 31)
- -- if any wrapped lines have changed, then reset WrapMode to fix the drawing
- if needfix then
- -- this fixes an issue with duplicate lines in Scintilla when
- -- invisible styles hide some of the content that would be wrapped.
- local wrapmode = editor:GetWrapMode()
- if wrapmode ~= wxstc.wxSTC_WRAP_NONE then editor:SetWrapMode(wrapmode) end
- -- if some of the lines have folded, this can make not styled lines visible
- custom_style(editor, linee+1) -- style to the end in this case
- end
- end
- --[[----------------------------------------------------------
- plugin locals
- ]]------------------------------------------------------------
- local G = ...
- local id = G.ID("ts_docpanel.referenceview")
- local refpanel = "ts_docpanel"
- local refeditor
- -- Add the documentaion panel
- local addDocumentationPanel = function()
- local e = wxstc.wxStyledTextCtrl(ide:GetMainFrame(), wx.wxID_ANY,
- wx.wxDefaultPosition, wx.wxSize(20, 20), wx.wxBORDER_NONE)
- refeditor = e
- -- Add the panel
- local w, h = 250, 250
- ide:AddPanel(e, refpanel, TR("Documentation"), function(pane)
- pane:Dock():Right():TopDockable(false):BottomDockable(false)
- :MinSize(w,-1):BestSize(w,-1):FloatingSize(w,h)
- end)
- -- Append our own styles to those of the IDE
- local numExistingStyles = #(ide.config.styles)
- local currentCustomStyle = 1
- for key,value in pairs(markup) do
- local style = {}
- -- copy all style features by value
- for feature in pairs(value) do
- style[feature] = value[feature]
- end
- style.fg = style.fg or {0, 0, 0}
- style.bg = style.bg or {255, 255, 255}
- style.st = numExistingStyles + currentCustomStyle
- currentCustomStyle = currentCustomStyle + 1
- ide.config.styles[key] = style
- end
- -- Make sure the default IDE styles are in our markup, too, or they won't be applied by
- -- the custom_style function
- for key,value in pairs(ide.config.styles) do
- if value["st"] ~= nil and value.st > 24 and value.st < 32 then
- markup[key] = value
- end
- end
- -- Register keywords and set the styles to use
- SetupKeywords(e, "lua", nil, ide.config.styles, ide.font.oNormal ,ide.font.oItalic)
- StylesApplyToEditor(ide.config.styles, e, ide.font.oNormal, ide.font.oItalic)
- -- Provide fake iscomment
- e.spec = {}
- e.spec.iscomment = {}
- for i = 0, 100 do
- e.spec.iscomment[i] = true
- end
- local font = ide:GetOutput():GetFont()
- e:SetFont(font)
- e:StyleSetFont(wxstc.wxSTC_STYLE_DEFAULT, font)
- e:SetReadOnly(true)
- e:SetWrapMode(wxstc.wxSTC_WRAP_WORD)
- -- remove all margins
- for m = 0, 4 do e:SetMarginWidth(m, 0) end
- -- disable dragging to the panel
- e:Connect(wxstc.wxEVT_STC_DO_DROP, function(event) event:SetDragResult(wx.wxDragNone) end)
- -- Connect to UI update to be able to style the document
- e:Connect(wxstc.wxEVT_STC_UPDATEUI, function(event)
- custom_style(e,0,e:GetLineCount()) -- style the entire document
- end)
- local menu = ide:GetMenuBar():GetMenu(ide:GetMenuBar():FindMenu(TR("&View")))
- menu:InsertCheckItem(4, id, TR("Documentation Panel")..KSC(id))
- menu:Connect(id, wx.wxEVT_COMMAND_MENU_SELECTED, function (event)
- local uimgr = ide:GetUIManager()
- uimgr:GetPane(refpanel):Show(not uimgr:GetPane(refpanel):IsShown())
- uimgr:Update()
- end)
- ide:GetMainFrame():Connect(id, wx.wxEVT_UPDATE_UI, function (event)
- local pane = ide:GetUIManager():GetPane(refpanel)
- menu:Enable(event:GetId(), pane:IsOk()) -- disable if doesn't exist
- menu:Check(event:GetId(), pane:IsOk() and pane:IsShown())
- end)
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement