├── LICENSE ├── README.md ├── dmd ├── comments.lua ├── cstyle.lua ├── icons.lua ├── init.lua └── snippets.lua └── img ├── alias.xpm ├── class.png ├── class.xpm ├── enum_dec.xpm ├── function.xpm ├── interface.xpm ├── keyword.xpm ├── module.xpm ├── package.xpm ├── screenshot.png ├── struct.xpm ├── template.xpm ├── union.xpm └── variable.xpm /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Brian Schott 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | textadept-d 2 | =========== 3 | D language plugin for Textadept 4 | 5 | ![Screenshot](img/screenshot.png) 6 | 7 | ## Features 8 | * Code autocomplete and DDOC display (DCD) 9 | * Go-to-declaration (DCD) 10 | * Inline code linting and syntax checking (D-Scanner) 11 | * Symbol index with go-to-declaration(D-Scanner) 12 | * Snippets 13 | * Supports Textredux and normal Textadept dialogs 14 | * Tested on Linux and Windows. (It should work on BSD and OS-X, but this is not tested) 15 | 16 | ## Requirements 17 | * Textadept 7.8 or later or Textadept nightly build dated 2015-01-06 or later 18 | * DCD 19 | * D-Scanner 20 | 21 | ## Installation 22 | * Download textadept-d and place the "dmd" folder in "~/.textadept/modules/" ("$HOME\.textadept\modules" on Windows) 23 | * Download and build [DCD](https://github.com/Hackerpilot/DCD/) 24 | * Download and build [D-Scanner](https://github.com/Hackerpilot/Dscanner/) 25 | * Place the dcd-server binary on your $PATH, or edit the line in dmd/init.lua that says ```M.PATH_TO_DCD_SERVER = "dcd-server"``` 26 | * Place the dcd-client binary on your $PATH, or edit the line in dmd/init.lua that says ```M.PATH_TO_DCD_CLIENT = "dcd-client"``` 27 | * Place the dscanner binary on your $PATH, or edit the line in dmd/init.lua that says ```M.PATH_TO_DSCANNER = "dscanner"``` 28 | 29 | ## Key Bindings 30 | Key|Action 31 | ---|------ 32 | *Ctrl+{*|Open brace and automatically indent next line 33 | *Ctrl+Enter*|Autocomplete 34 | *Ctrl+Shift+G*|Go to declaration of symbol at cursor 35 | *Ctrl+Alt+Shift+G*|Go back after jumping to declaration 36 | *Ctrl+Shift+M*|Display symbol index for current file 37 | *Ctrl+;*|Go to end of line, insert semicolon 38 | *Shift+Enter*|Go to end of line, insert semicolon, insert newline 39 | *Enter*|Newline with automatic multi-line comment continuation 40 | *Ctrl+Shift+H*|Show ddoc for symbol at cursor 41 | -------------------------------------------------------------------------------- /dmd/comments.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | -------------------------------------------------------------------------------- 4 | -- Continues /* */ style comments 5 | -- @return true if other functions should try to handle the event 6 | -- @param block_start_chars The characters that define the start of a stream 7 | -- comment 8 | -- @param block_middle_chars The characters that define the middle of a stream 9 | -- comment. This can be an empty string 10 | -- @param block_end_chars The characters that define the end of a stream 11 | -- comment 12 | -- @param block_start_pattern The lua pattern that defines the start of a 13 | -- stream comment. This is necessary because block_start_chars might 14 | -- contain characters that need to be escaped 15 | -- @param block_middle_pattern The lua pattern for the middle of a comment. 16 | -- This can be an empty string 17 | -- @param block_end_pattern The lua pattern for the end of a comment. 18 | -------------------------------------------------------------------------------- 19 | function M.continue_block_comment(block_start_chars, block_middle_chars, 20 | block_end_chars, block_start_pattern, block_middle_pattern, 21 | block_end_pattern) 22 | -- Check with the lexer to see if we're actually in a comment. Otherwise 23 | -- this code will think that a multi-line multiplication is a C comment 24 | -- because of lines beginning with "*" 25 | if buffer:name_of_style(buffer.style_at[buffer.current_pos]) ~= "comment" then 26 | return true 27 | end 28 | 29 | local line_num = buffer:line_from_position(buffer.current_pos) 30 | local prev_line = buffer:get_line(line_num - 1) 31 | local curr_line = buffer:get_line(line_num + 1) 32 | local prev_is_end = prev_line:find(block_end_pattern.."%s*$") ~= nil 33 | local prev_is_middle = prev_line:find("^%s*"..block_middle_pattern) ~= nil 34 | local curr_is_middle = curr_line:find("^%s*"..block_middle_pattern) ~= nil 35 | local prev_is_start = prev_line:find("^%s*"..block_start_pattern) ~= nil 36 | if prev_is_end then 37 | buffer:null() 38 | elseif prev_is_middle or (curr_is_middle and prev_is_start) then 39 | local indent = buffer.line_indentation[line_num - 1] 40 | buffer:add_text(block_middle_chars) 41 | local aftermiddle = prev_line:match( 42 | "^%s*"..block_middle_pattern.."([ \t]+)") 43 | if aftermiddle ~= nil then 44 | buffer:add_text(aftermiddle) 45 | elseif prev_is_start then 46 | buffer:add_text(" ") 47 | end 48 | if prev_is_start then 49 | buffer.line_indentation[line_num] = indent + 1 50 | else 51 | buffer.line_indentation[line_num] = indent 52 | end 53 | return false 54 | elseif prev_is_start then 55 | local indent = buffer.line_indentation[line_num - 1] 56 | buffer:add_text(' '..block_middle_chars..' ') 57 | buffer:line_end() 58 | buffer:new_line() 59 | buffer:add_text(block_end_chars) 60 | buffer:line_up() 61 | buffer:line_end() 62 | return false 63 | else 64 | return true 65 | end 66 | end 67 | 68 | 69 | -------------------------------------------------------------------------------- 70 | -- Continues single-line comments 71 | -- @return true if other functions should try to handle the event 72 | -- @param line_pattern The lua pattern for the start of the comment 73 | -- @param line_chars The characters for the start of the comment 74 | -------------------------------------------------------------------------------- 75 | function M.continue_line_comment(line_chars, line_pattern) 76 | local line_num = buffer:line_from_position(buffer.current_pos) 77 | local prev_line = buffer:get_line(line_num - 1) 78 | if prev_line:find(line_pattern.."%s*$") then 79 | buffer:line_up() 80 | buffer:line_end() 81 | buffer:del_line_left() 82 | buffer:delete_back() 83 | buffer:line_down() 84 | return false 85 | elseif prev_line:find("^%s*"..line_pattern) then 86 | local indent = buffer.line_indentation[line_num - 1] 87 | buffer:add_text(line_chars) 88 | local aftercomment = prev_line:match( 89 | "^%s*"..line_pattern.."([ \t]+)") 90 | if aftercomment ~= nil then 91 | buffer:add_text(aftercomment) 92 | end 93 | p = buffer.current_pos 94 | buffer.line_indentation[line_num] = indent 95 | buffer:goto_pos(p) 96 | return false 97 | else 98 | return true 99 | end 100 | end 101 | 102 | return M 103 | -------------------------------------------------------------------------------- /dmd/cstyle.lua: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- 2 | -- Functions for C-style languages such as C,C++,C#,D, and Java 3 | -------------------------------------------------------------------------------- 4 | 5 | local M = {} 6 | 7 | local comments = require 'dmd.comments' 8 | local continue_block_comment = comments.continue_block_comment 9 | local continue_line_comment = comments.continue_line_comment 10 | 11 | -------------------------------------------------------------------------------- 12 | -- Selects the scope that the cursor is currently inside of. 13 | -------------------------------------------------------------------------------- 14 | function M.selectScope() 15 | local cursor = buffer.current_pos 16 | local depth = -1 17 | while depth ~= 0 do 18 | buffer:search_anchor() 19 | if buffer:search_prev(2097158, "[{}()]") < 0 then break end 20 | if buffer.current_pos == 0 then break end 21 | if buffer:get_sel_text():match("[)}]") then 22 | depth = depth - 1 23 | else 24 | depth = depth + 1 25 | end 26 | end 27 | local scopeBegin = buffer.current_pos 28 | local scopeEnd = buffer:brace_match(buffer.current_pos) 29 | buffer:set_sel(scopeBegin, scopeEnd + 1) 30 | end 31 | 32 | -- Returns true if other functions should try to handle the event 33 | function M.indent_after_brace() 34 | local buffer = buffer 35 | local line_num = buffer:line_from_position(buffer.current_pos) 36 | local prev_line = buffer:get_line(line_num - 1) 37 | local curr_line = buffer:get_line(line_num) 38 | if prev_line:find("{%s*$") then 39 | local indent = buffer.line_indentation[line_num - 1] 40 | local new_indent = indent 41 | if buffer.indent == 0 then new_indent = new_indent + buffer.tab_width end 42 | if curr_line:find("}") then 43 | buffer:new_line() 44 | buffer.line_indentation[line_num] = new_indent 45 | buffer.line_indentation[line_num + 1] = indent 46 | buffer:line_up() 47 | buffer:line_end() 48 | else 49 | buffer.line_indentation[line_num] = new_indent 50 | buffer:line_end() 51 | end 52 | return false 53 | else 54 | return true 55 | end 56 | end 57 | 58 | -- Matches the closing } character with the indent level of its corresponding { 59 | -- Does not properly handle the case of an opening brace inside a string. 60 | function M.match_brace_indent() 61 | local buffer = buffer 62 | local style = buffer.style_at[buffer.current_pos] 63 | -- Don't do this if in a comment or string 64 | if style == 3 or style == 2 then return false end 65 | buffer:begin_undo_action() 66 | local line_num = buffer:line_from_position(buffer.current_pos) 67 | local brace_count = 1 -- +1 for closing, -1 for opening 68 | for i = line_num,0,-1 do 69 | local il = buffer:get_line(i) 70 | if il:find("{") then 71 | brace_count = brace_count - 1 72 | elseif il:find("}") then 73 | brace_count = brace_count + 1 74 | end 75 | if brace_count == 0 then 76 | buffer:line_up() 77 | buffer.line_indentation[line_num] = buffer.line_indentation[i] 78 | buffer:line_down() 79 | break 80 | end 81 | end 82 | buffer:end_undo_action() 83 | return false 84 | end 85 | 86 | -- Call this when the enter key is pressed 87 | function M.enter_key_pressed() 88 | if buffer:auto_c_active() then return false end 89 | buffer:begin_undo_action() 90 | buffer:new_line() 91 | local cont = M.indent_after_brace() 92 | if cont then 93 | cont = continue_block_comment("/**", "*", "*/", "/%*", "%*", "%*/") 94 | end 95 | if cont then 96 | cont = continue_block_comment("/+", "+", "+/", "/%+", "%+", "%+/") 97 | end 98 | if cont then 99 | cont = continue_line_comment("//", "//") 100 | end 101 | buffer:end_undo_action() 102 | end 103 | 104 | function M.endline_semicolon() 105 | buffer:begin_undo_action() 106 | buffer:line_end() 107 | buffer:add_text(';') 108 | buffer:end_undo_action() 109 | end 110 | 111 | function M.newline_semicolon() 112 | buffer:begin_undo_action() 113 | buffer:line_end() 114 | buffer:add_text(';') 115 | buffer:new_line() 116 | buffer:end_undo_action() 117 | end 118 | 119 | function M.newline() 120 | buffer:begin_undo_action() 121 | buffer:line_end() 122 | buffer:new_line() 123 | buffer:end_undo_action() 124 | end 125 | 126 | -- allmanStyle: true to newline before opening brace, false for K&R style 127 | function M.openBraceMagic(allmanStyle) 128 | buffer:begin_undo_action() 129 | buffer:line_end() 130 | if allmanStyle then 131 | buffer:new_line() 132 | else 133 | if buffer.char_at[buffer.current_pos - 1] ~= string.byte(" ") then 134 | buffer:add_text(" ") 135 | end 136 | end 137 | buffer:add_text("{}") 138 | buffer:char_left() 139 | M.enter_key_pressed() 140 | buffer:end_undo_action() 141 | end 142 | 143 | return M 144 | -------------------------------------------------------------------------------- /dmd/icons.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | M.ALIAS =[[ 4 | /* XPM */ 5 | static char * alias_xpm[] = { 6 | "16 16 17 1", 7 | " c None", 8 | ". c #547AA0", 9 | "+ c #547BA2", 10 | "@ c #547CA4", 11 | "# c #F0F0F0", 12 | "$ c #547DA6", 13 | "% c #F5F5F5", 14 | "& c #547EA8", 15 | "* c #FBFBFB", 16 | "= c #F7F7F7", 17 | "- c #F2F2F2", 18 | "; c #547BA3", 19 | "> c #ECECEC", 20 | ", c #547AA1", 21 | "' c #E7E7E7", 22 | ") c #54799F", 23 | "! c #54789D", 24 | " ", 25 | " ", 26 | " .......... ", 27 | " ++++++++++++ ", 28 | " @@@@@##@@@@@ ", 29 | " $$$$%%%%$$$$ ", 30 | " &&&&****&&&& ", 31 | " &&&==&&==&&& ", 32 | " $$$==$$==$$$ ", 33 | " @@@------@@@ ", 34 | " ;;>>>>>>>>;; ", 35 | " ,,'',,,,'',, ", 36 | " )))))))))))) ", 37 | " !!!!!!!!!! ", 38 | " ", 39 | " "}; 40 | ]] 41 | 42 | -- union icon 43 | M.UNION = [[ 44 | /* XPM */ 45 | static char * union_xpm[] = { 46 | "16 16 18 1", 47 | " c None", 48 | ". c #A06B35", 49 | "+ c #A87038", 50 | "@ c #AC7339", 51 | "# c #F7EFE7", 52 | "$ c #AF753A", 53 | "% c #F9F4EE", 54 | "& c #B3783C", 55 | "* c #FCFAF7", 56 | "= c #FDFBF8", 57 | "- c #B1763B", 58 | "; c #FAF5F0", 59 | "> c #F8F1EA", 60 | ", c #A97138", 61 | "' c #F4EBE1", 62 | ") c #A36D36", 63 | "! c #F2E6D9", 64 | "~ c #9C6833", 65 | " ", 66 | " ", 67 | " .......... ", 68 | " ++++++++++++ ", 69 | " @@##@@@@##@@ ", 70 | " $$%%$$$$%%$$ ", 71 | " &&**&&&&**&& ", 72 | " &&==&&&&==&& ", 73 | " --;;----;;-- ", 74 | " @@>>@@@@>>@@ ", 75 | " ,,'''''''',, ", 76 | " )))!!!!!!))) ", 77 | " ............ ", 78 | " ~~~~~~~~~~ ", 79 | " ", 80 | " "}; 81 | ]] 82 | 83 | -- class icon 84 | M.CLASS = [[ 85 | /* XPM */ 86 | static char * class_xpm[] = { 87 | "16 16 18 1", 88 | " c None", 89 | ". c #006AD6", 90 | "+ c #006DDC", 91 | "@ c #0070E2", 92 | "# c #F0F0F0", 93 | "$ c #0072E6", 94 | "% c #F5F5F5", 95 | "& c #0075EC", 96 | "* c #FBFBFB", 97 | "= c #F7F7F7", 98 | "- c #0073E8", 99 | "; c #F2F2F2", 100 | "> c #006EDE", 101 | ", c #ECECEC", 102 | "' c #006BD8", 103 | ") c #E7E7E7", 104 | "! c #0069D4", 105 | "~ c #0066CE", 106 | " ", 107 | " ", 108 | " .......... ", 109 | " ++++++++++++ ", 110 | " @@@@#####@@@ ", 111 | " $$$%%%%%%%$$ ", 112 | " &&***&&&**&& ", 113 | " &&==&&&&&&&& ", 114 | " --==-------- ", 115 | " @@;;;@@@;;@@ ", 116 | " >>>,,,,,,,>> ", 117 | " '''')))))''' ", 118 | " !!!!!!!!!!!! ", 119 | " ~~~~~~~~~~ ", 120 | " ", 121 | " "}; 122 | ]] 123 | 124 | 125 | -- interface icon 126 | M.INTERFACE = [[ 127 | /* XPM */ 128 | static char * interface_xpm[] = { 129 | "16 16 19 1", 130 | " c None", 131 | ". c #CC7729", 132 | "+ c #D47D2D", 133 | "@ c #D58032", 134 | "# c #F0F0F0", 135 | "$ c #D58134", 136 | "% c #FFFFFF", 137 | "& c #F5F5F5", 138 | "* c #D6853B", 139 | "= c #FBFBFB", 140 | "- c #FDFDFD", 141 | "; c #D58236", 142 | "> c #F7F7F7", 143 | ", c #F2F2F2", 144 | "' c #ECECEC", 145 | ") c #CF792A", 146 | "! c #E7E7E7", 147 | "~ c #CA7629", 148 | "{ c #C37228", 149 | " ", 150 | " ", 151 | " .......... ", 152 | " ++++++++++++ ", 153 | " @@@######@@@ ", 154 | " $$$%&&&&&$$$ ", 155 | " *****==***** ", 156 | " *****--***** ", 157 | " ;;;;;>>;;;;; ", 158 | " @@@@@,,@@@@@ ", 159 | " +++''''''+++ ", 160 | " )))!!!!!!))) ", 161 | " ~~~~~~~~~~~~ ", 162 | " {{{{{{{{{{ ", 163 | " ", 164 | " "}; 165 | ]] 166 | 167 | -- struct icon 168 | M.STRUCT = [[ 169 | /* XPM */ 170 | static char * struct_xpm[] = { 171 | "16 16 19 1", 172 | " c None", 173 | ". c #000098", 174 | "+ c #00009E", 175 | "@ c #0000A2", 176 | "# c #F0F0F0", 177 | "$ c #0000A4", 178 | "% c #F5F5F5", 179 | "& c #FFFFFF", 180 | "* c #0000A8", 181 | "= c #FBFBFB", 182 | "- c #FDFDFD", 183 | "; c #0000A6", 184 | "> c #F7F7F7", 185 | ", c #F2F2F2", 186 | "' c #ECECEC", 187 | ") c #00009A", 188 | "! c #E7E7E7", 189 | "~ c #000096", 190 | "{ c #000092", 191 | " ", 192 | " ", 193 | " .......... ", 194 | " ++++++++++++ ", 195 | " @@@#######@@ ", 196 | " $$%&%%%%%%$$ ", 197 | " **===******* ", 198 | " **-------*** ", 199 | " ;;;>>>>>>>;; ", 200 | " @@@@@@@,,,@@ ", 201 | " ++''''''''++ ", 202 | " ))!!!!!!!))) ", 203 | " ~~~~~~~~~~~~ ", 204 | " {{{{{{{{{{ ", 205 | " ", 206 | " "}; 207 | ]] 208 | 209 | -- functions icon 210 | M.FUNCTION = [[ 211 | /* XPM */ 212 | static char * function_xpm[] = { 213 | "16 16 17 1", 214 | " c None", 215 | ". c #317025", 216 | "+ c #367B28", 217 | "@ c #387F2A", 218 | "# c #F0F0F0", 219 | "$ c #FFFFFF", 220 | "% c #F5F5F5", 221 | "& c #3A832C", 222 | "* c #FBFBFB", 223 | "= c #FDFDFD", 224 | "- c #F7F7F7", 225 | "; c #F2F2F2", 226 | "> c #ECECEC", 227 | ", c #347627", 228 | "' c #E7E7E7", 229 | ") c #306D24", 230 | "! c #2F6A23", 231 | " ", 232 | " ", 233 | " .......... ", 234 | " ++++++++++++ ", 235 | " @@@######@@@ ", 236 | " @@@$%%%%%@@@ ", 237 | " &&&**&&&&&&& ", 238 | " &&&=====&&&& ", 239 | " @@@-----@@@@ ", 240 | " @@@;;@@@@@@@ ", 241 | " +++>>+++++++ ", 242 | " ,,,'',,,,,,, ", 243 | " )))))))))))) ", 244 | " !!!!!!!!!! ", 245 | " ", 246 | " "}; 247 | ]] 248 | 249 | -- fields icon 250 | M.FIELD = [[ 251 | /* XPM */ 252 | static char * variable_xpm[] = { 253 | "16 16 18 1", 254 | " c None", 255 | ". c #933093", 256 | "+ c #A035A0", 257 | "@ c #A537A5", 258 | "# c #FFFFFF", 259 | "$ c #F0F0F0", 260 | "% c #A637A6", 261 | "& c #F5F5F5", 262 | "* c #AC39AC", 263 | "= c #FBFBFB", 264 | "- c #FDFDFD", 265 | "; c #F7F7F7", 266 | "> c #F2F2F2", 267 | ", c #ECECEC", 268 | "' c #9A339A", 269 | ") c #E7E7E7", 270 | "! c #8E2F8E", 271 | "~ c #8B2E8B", 272 | " ", 273 | " ", 274 | " .......... ", 275 | " ++++++++++++ ", 276 | " @@#$@@@@$$@@ ", 277 | " %%&#%%%%&&%% ", 278 | " **==****==** ", 279 | " ***--**--*** ", 280 | " %%%;;%%;;%%% ", 281 | " @@@@>>>>@@@@ ", 282 | " ++++,,,,++++ ", 283 | " '''''))''''' ", 284 | " !!!!!!!!!!!! ", 285 | " ~~~~~~~~~~ ", 286 | " ", 287 | " "}; 288 | ]] 289 | 290 | --package icon 291 | M.PACKAGE = [[ 292 | /* XPM */ 293 | static char * package_xpm[] = { 294 | "16 16 6 1", 295 | " c None", 296 | ". c #000100", 297 | "+ c #050777", 298 | "@ c #242BAE", 299 | "# c #2E36BF", 300 | "$ c #434FE5", 301 | " ", 302 | " ............ ", 303 | " .$$$$$$$$$$$$. ", 304 | " .$##@@+$##@@+. ", 305 | " .$#@@@+$#@@@+. ", 306 | " .$@@@#+$@@@#+. ", 307 | " .$@@##+$@@##+. ", 308 | " .$+++++$+++++. ", 309 | " .$$$$$$$$$$$$. ", 310 | " .$##@@+$##@@+. ", 311 | " .$#@@@+$#@@@+. ", 312 | " .$@@@#+$@@@#+. ", 313 | " .$@@##+$@@##+. ", 314 | " .$+++++$+++++. ", 315 | " ............ ", 316 | " "}; 317 | ]] 318 | 319 | -- module icon 320 | M.MODULE = [[ 321 | /* XPM */ 322 | static char * module_xpm[] = { 323 | "16 16 14 1", 324 | " c None", 325 | ". c #000000", 326 | "+ c #000100", 327 | "@ c #FFFF83", 328 | "# c #FFFF00", 329 | "$ c #FFFF28", 330 | "% c #FFFF6A", 331 | "& c #FFFF4C", 332 | "* c #D5D500", 333 | "= c #CDCD00", 334 | "- c #A3A300", 335 | "; c #B2B200", 336 | "> c #C3C300", 337 | ", c #919100", 338 | " ", 339 | " .+ ", 340 | " .@#+ ", 341 | " .@#+ ", 342 | " .$@##+ ", 343 | " ..%@##++ ", 344 | " ..&%%@####++ ", 345 | " .@@@@@%######+ ", 346 | " +*****=-;;;;;+ ", 347 | " ++>==*;--,.. ", 348 | " ++=*;-.. ", 349 | " +>*;,. ", 350 | " +*;. ", 351 | " +*;. ", 352 | " ++ ", 353 | " "}; 354 | ]] 355 | 356 | -- enum icon 357 | M.ENUM = [[ 358 | /* XPM */ 359 | static char * enum_dec_xpm[] = { 360 | "16 16 18 1", 361 | " c None", 362 | ". c #6D43C0", 363 | "+ c #754EC3", 364 | "@ c #7751C4", 365 | "# c #F0F0F0", 366 | "$ c #7852C5", 367 | "% c #FFFFFF", 368 | "& c #F5F5F5", 369 | "* c #7D58C7", 370 | "= c #FBFBFB", 371 | "- c #FDFDFD", 372 | "; c #F7F7F7", 373 | "> c #F2F2F2", 374 | ", c #ECECEC", 375 | "' c #7048C2", 376 | ") c #E7E7E7", 377 | "! c #6A40BF", 378 | "~ c #673EBA", 379 | " ", 380 | " ", 381 | " .......... ", 382 | " ++++++++++++ ", 383 | " @@@######@@@ ", 384 | " $$$%&&&&&$$$ ", 385 | " ***==******* ", 386 | " ***-----**** ", 387 | " $$$;;;;;$$$$ ", 388 | " @@@>>@@@@@@@ ", 389 | " +++,,,,,,+++ ", 390 | " '''))))))''' ", 391 | " !!!!!!!!!!!! ", 392 | " ~~~~~~~~~~ ", 393 | " ", 394 | " "}; 395 | ]] 396 | 397 | -- keyword icon 398 | M.KEYWORD = [[ 399 | /* XPM */ 400 | static char * keyword_xpm[] = { 401 | "16 16 24 1", 402 | " c None", 403 | ". c #B91C1C", 404 | "+ c #BA1C1C", 405 | "@ c #BE1D1D", 406 | "# c #C31E1E", 407 | "$ c #C21E1E", 408 | "% c #F0F0F0", 409 | "& c #C71E1E", 410 | "* c #F5F5F5", 411 | "= c #CC1F1F", 412 | "- c #FBFBFB", 413 | "; c #CB1F1F", 414 | "> c #CD1F1F", 415 | ", c #FDFDFD", 416 | "' c #C91F1F", 417 | ") c #F7F7F7", 418 | "! c #C41E1E", 419 | "~ c #F2F2F2", 420 | "{ c #C01D1D", 421 | "q c #ECECEC", 422 | "^ c #BB1D1D", 423 | "/ c #E7E7E7", 424 | "( c #B71C1C", 425 | "_ c #B21B1B", 426 | " ", 427 | " ", 428 | " .......... ", 429 | " @@@@@@@@@@@@ ", 430 | " #$%%%%%%$$#$ ", 431 | " &&*******&&& ", 432 | " ==--==;---== ", 433 | " >>,,>>>>,,>> ", 434 | " ''))''''))'' ", 435 | " !!~~!!!~~~!! ", 436 | " {{qqqqqqq{{{ ", 437 | " ^^//////^^^^ ", 438 | " (((((((((((( ", 439 | " __________ ", 440 | " ", 441 | " "}; 442 | ]] 443 | 444 | -- template icon 445 | M.TEMPLATE = [[ 446 | /* XPM */ 447 | static char * template_xpm[] = { 448 | "16 16 14 1", 449 | " c None", 450 | ". c #00A2A4", 451 | "+ c #00A9AB", 452 | "@ c #E1FFFF", 453 | "# c #EBFFFF", 454 | "$ c #F7FFFF", 455 | "% c #FBFFFF", 456 | "& c #EFFFFF", 457 | "* c #E5FFFF", 458 | "= c #D9FFFF", 459 | "- c #00A5A7", 460 | "; c #CFFEFF", 461 | "> c #00A0A3", 462 | ", c #009A9C", 463 | " ", 464 | " ", 465 | " .......... ", 466 | " ++++++++++++ ", 467 | " +++@@@@@@+++ ", 468 | " +++######+++ ", 469 | " +++++$$+++++ ", 470 | " +++++%%+++++ ", 471 | " +++++&&+++++ ", 472 | " +++++**+++++ ", 473 | " +++++==+++++ ", 474 | " -----;;----- ", 475 | " >>>>>>>>>>>> ", 476 | " ,,,,,,,,,, ", 477 | " ", 478 | " "}; 479 | ]] 480 | 481 | return M 482 | -------------------------------------------------------------------------------- /dmd/init.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | local cstyle = require "dmd.cstyle" 4 | local icons = require "dmd.icons" 5 | local dsnippets = require "dmd.snippets" 6 | local snippets = _G.snippets 7 | local keys = _G.keys 8 | 9 | -- Used for dscanner/ctags symbol finder 10 | local lineDict = {} 11 | 12 | -- Used for DCD call tips 13 | local calltips = {} 14 | local currentCalltip = 1 15 | 16 | M.PATH_TO_DCD_SERVER = "dcd-server" 17 | M.PATH_TO_DCD_CLIENT = "dcd-client" 18 | M.PATH_TO_DSCANNER = "dscanner" 19 | M.PATH_TO_DFMT = "dfmt" 20 | 21 | textadept.editing.comment_string.dmd = '//' 22 | textadept.run.compile_commands.dmd = 'dmd -c -o- %(filename)' 23 | textadept.run.error_patterns.dmd = { 24 | pattern = '^(.-)%((%d+)%): (.+)$', 25 | filename = 1, line = 2, message = 3 26 | } 27 | 28 | M.kindToIconMapping = {} 29 | M.kindToIconMapping['a'] = _SCINTILLA.next_image_type() 30 | M.kindToIconMapping['A'] = _SCINTILLA.next_image_type() 31 | M.kindToIconMapping['c'] = _SCINTILLA.next_image_type() 32 | M.kindToIconMapping['e'] = _SCINTILLA.next_image_type() 33 | M.kindToIconMapping['f'] = _SCINTILLA.next_image_type() 34 | M.kindToIconMapping['h'] = _SCINTILLA.next_image_type() 35 | M.kindToIconMapping['i'] = _SCINTILLA.next_image_type() 36 | M.kindToIconMapping['k'] = _SCINTILLA.next_image_type() 37 | M.kindToIconMapping['l'] = _SCINTILLA.next_image_type() 38 | M.kindToIconMapping['M'] = _SCINTILLA.next_image_type() 39 | M.kindToIconMapping['P'] = _SCINTILLA.next_image_type() 40 | M.kindToIconMapping['s'] = _SCINTILLA.next_image_type() 41 | M.kindToIconMapping['t'] = _SCINTILLA.next_image_type() 42 | M.kindToIconMapping['u'] = _SCINTILLA.next_image_type() 43 | M.kindToIconMapping['v'] = _SCINTILLA.next_image_type() 44 | 45 | M.kindToIconMapping['g'] = M.kindToIconMapping['e'] 46 | M.kindToIconMapping['m'] = M.kindToIconMapping['v'] 47 | M.kindToIconMapping['p'] = M.kindToIconMapping['t'] 48 | M.kindToIconMapping['T'] = M.kindToIconMapping['t'] 49 | 50 | local function registerImages() 51 | view:register_image(M.kindToIconMapping['c'], icons.CLASS) 52 | view:register_image(M.kindToIconMapping['e'], icons.ENUM) 53 | view:register_image(M.kindToIconMapping['f'], icons.FUNCTION) 54 | view:register_image(M.kindToIconMapping['i'], icons.INTERFACE) 55 | view:register_image(M.kindToIconMapping['k'], icons.KEYWORD) 56 | view:register_image(M.kindToIconMapping['l'], icons.ALIAS) 57 | view:register_image(M.kindToIconMapping['M'], icons.MODULE) 58 | view:register_image(M.kindToIconMapping['P'], icons.PACKAGE) 59 | view:register_image(M.kindToIconMapping['s'], icons.STRUCT) 60 | view:register_image(M.kindToIconMapping['t'], icons.TEMPLATE) 61 | view:register_image(M.kindToIconMapping['u'], icons.UNION) 62 | view:register_image(M.kindToIconMapping['v'], icons.FIELD) 63 | end 64 | 65 | local function showCompletionList(r) 66 | buffer.auto_c_choose_single = false; 67 | buffer.auto_c_max_width = 0 68 | local completions = {} 69 | for symbol, kind in r:gmatch("([^%s]+)\t(%a)\r?\n") do 70 | completions[#completions + 1] = symbol .. "?" .. M.kindToIconMapping[kind] 71 | end 72 | table.sort(completions, function(a, b) return string.upper(a) < string.upper(b) end) 73 | local charactersEntered = buffer.current_pos - buffer:word_start_position(buffer.current_pos) 74 | local prevChar = buffer.char_at[buffer.current_pos - 1] 75 | if prevChar == string.byte('.') 76 | or prevChar == string.byte(':') 77 | or prevChar == string.byte(' ') 78 | or prevChar == string.byte('\t') 79 | or prevChar == string.byte('(') 80 | or prevChar == string.byte('[') then 81 | charactersEntered = 0 82 | end 83 | if not buffer:auto_c_active() then registerImages() end 84 | local setting = buffer.auto_c_choose_single 85 | buffer:auto_c_show(charactersEntered, table.concat(completions, " ")) 86 | buffer.auto_c_choose_single = setting 87 | end 88 | 89 | local function showCurrentCallTip() 90 | local tip = calltips[currentCalltip] 91 | view:call_tip_show(buffer:word_start_position(buffer.current_pos), 92 | string.format("%d of %d\1\2\n%s", currentCalltip, #calltips, 93 | calltips[currentCalltip]:gsub("(%f[\\])\\n", "%1\n") 94 | :gsub("\\\\n", "\\n"))) 95 | end 96 | 97 | local function showCalltips(calltip) 98 | currentCalltip = 1 99 | calltips = {} 100 | for tip in calltip:gmatch("(.-)\r?\n") do 101 | if tip ~= "calltips" then 102 | table.insert(calltips, tip) 103 | end 104 | end 105 | if (#calltips > 0) then 106 | showCurrentCallTip() 107 | end 108 | end 109 | 110 | local function cycleCalltips(delta) 111 | if not buffer:call_tip_active() then 112 | return false 113 | end 114 | if delta > 0 then 115 | currentCalltip = math.max(math.min(#calltips, currentCalltip + 1), 1) 116 | else 117 | currentCalltip = math.min(math.max(1, currentCalltip - 1), #calltips) 118 | end 119 | showCurrentCallTip() 120 | end 121 | 122 | local function runDCDClient(args) 123 | local command = M.PATH_TO_DCD_CLIENT .. " " .. args .. " -c" .. buffer.current_pos - 1 124 | local p = os.spawn(command) 125 | p:write(buffer:get_text():sub(1, buffer.length)) 126 | p:close() 127 | return p:read("*a") or "" 128 | end 129 | 130 | local function showDoc() 131 | local r = runDCDClient("-d") 132 | if r ~= "\n" then 133 | showCalltips(r) 134 | end 135 | end 136 | 137 | 138 | M.gotoStack = {} 139 | 140 | function M.goBack() 141 | if #M.gotoStack == 0 then return end 142 | local top = M.gotoStack[#M.gotoStack] 143 | if top.file ~= nil then 144 | ui.goto_file(top.file, false, _VIEWS[top.view]) 145 | else 146 | if top.buffer > _BUFFERS then 147 | table.remove(M.gotoStack) 148 | return 149 | end 150 | view:goto_buffer(top.buffer) 151 | end 152 | buffer:goto_line(top.line) 153 | buffer:vertical_centre_caret() 154 | table.remove(M.gotoStack) -- pop last item 155 | end 156 | 157 | function M.gotoDeclaration() 158 | local r = runDCDClient("-l") 159 | if r ~= "Not found\n" then 160 | path, position = r:match("^(.-)\t(%d+)") 161 | if (path ~= nil and position ~= nil) then 162 | table.insert(M.gotoStack, { 163 | line = buffer:line_from_position(buffer.current_pos), 164 | file = buffer.filename, 165 | buffer = _BUFFERS[_G.buffer], 166 | view = _VIEWS[_G.view] 167 | }) 168 | if (path ~= "stdin") then 169 | ui.goto_file(path, false, _G.view) 170 | end 171 | buffer:goto_pos(tonumber(position)) 172 | buffer:vertical_centre_caret() 173 | buffer:word_right_end_extend() 174 | end 175 | end 176 | end 177 | 178 | local function expandContext(meta) 179 | local patterns = {"struct:(%w+)", "class:([%w_]+)", "template:([%w_]+)", 180 | "interface:([%w_]+)", "union:([%w_]+)", "function:([%w_]+)"} 181 | if meta == nil or meta == "" then return "" end 182 | for item in meta:gmatch("%w+:[%w%d_]+") do 183 | for _, pattern in ipairs(patterns) do 184 | local result = item:match(pattern) 185 | if result ~= nil then return result end 186 | end 187 | end 188 | return "" 189 | end 190 | 191 | -- Expands ctags type abbreviations to full words 192 | local function expandCtagsType(tagType) 193 | if tagType == "g" then return "enum" 194 | elseif tagType == "e" then return "" 195 | elseif tagType == "v" then return "variable" 196 | elseif tagType == "i" then return "interface" 197 | elseif tagType == "c" then return "class" 198 | elseif tagType == "s" then return "struct" 199 | elseif tagType == "f" then return "function" 200 | elseif tagType == "u" then return "union" 201 | elseif tagType == "T" then return "template" 202 | else return "" end 203 | end 204 | 205 | local function onSymbolListSelection(list, item) 206 | list:close() 207 | buffer:goto_line(item[4]) 208 | buffer:vertical_centre_caret() 209 | end 210 | 211 | -- Uses dscanner's --ctags option to create a symbol index for the contents of 212 | -- the buffer. Automatically uses Textadept's normal dialogs or textredux lists. 213 | local function symbolIndex() 214 | local fileName = os.tmpname() 215 | local mode = "w" 216 | if _G.WIN32 then mode = "wb" end 217 | local tmpFile = io.open(fileName, mode) 218 | tmpFile:write(buffer:get_text():sub(1, buffer.length)) 219 | tmpFile:flush() 220 | tmpFile:close() 221 | local command = M.PATH_TO_DSCANNER .. " --ctags " .. fileName 222 | local p = os.spawn(command) 223 | local r = p:read("*a") 224 | os.remove(fileName) 225 | local symbolList = {} 226 | local i = 0 227 | 228 | for line in r:gmatch("(.-)\r?\n") do 229 | if not line:match("^!") then 230 | local name, file, lineNumber, tagType, meta = line:match( 231 | "([~%w_]+)\t([%w/\\._ ]+)\t(%d+);\"\t(%w)\t?(.*)") 232 | if package.loaded['textredux'] then 233 | table.insert(symbolList, {name, expandCtagsType(tagType), expandContext(meta), lineNumber}) 234 | else 235 | table.insert(symbolList, name) 236 | table.insert(symbolList, expandCtagsType(tagType)) 237 | table.insert(symbolList, expandContext(meta)) 238 | table.insert(symbolList, lineNumber) 239 | end 240 | lineDict[i + 1] = tonumber(lineNumber) 241 | i = i + 1 242 | end 243 | end 244 | 245 | local headers = {"Name", "Kind", "Context", "Line"} 246 | 247 | if package.loaded['textredux'] then 248 | local reduxlist = require 'textredux.core.list' 249 | local reduxstyle = require 'textredux.core.style' 250 | local list = reduxlist.new('Go to symbol') 251 | list.items = symbolList 252 | list.on_selection = onSymbolListSelection 253 | list.headers = headers 254 | list.column_styles = { reduxstyle.variable, reduxstyle.keyword, reduxstyle.class, reduxstyle.number } 255 | list:show() 256 | else 257 | local button, i = ui.dialogs.filteredlist{ 258 | title = "Go to symbol", 259 | columns = headers, 260 | items = symbolList 261 | } 262 | if i ~= nil then 263 | buffer:goto_line(lineDict[i]) 264 | buffer:vertical_centre_caret() 265 | end 266 | end 267 | end 268 | 269 | local function autocomplete() 270 | if not buffer:auto_c_active() then registerImages() end 271 | local r = runDCDClient("") 272 | if r ~= "\n" and r ~= "\r\n" then 273 | if r:match("^identifiers.*") then 274 | showCompletionList(r) 275 | else 276 | showCalltips(r) 277 | end 278 | end 279 | if not buffer:auto_c_active() then 280 | textadept.editing.autocomplete("word") 281 | end 282 | end 283 | 284 | -- Autocomplete handler. Launches DCD on '(', '.', or ':' character insertion 285 | events.connect(events.CHAR_ADDED, function(ch) 286 | if buffer:get_lexer() ~= "dmd" or ch > 255 then return end 287 | if string.char(ch) == '(' or string.char(ch) == '.' or string.char(ch) == ':' then 288 | local setting = buffer.auto_c_choose_single 289 | buffer.auto_c_choose_single = false 290 | autocomplete(ch) 291 | buffer.auto_c_choose_single = setting 292 | end 293 | end) 294 | 295 | -- Run dscanner's static analysis after saves and print the warnings and errors 296 | -- reported to the buffer as annotations 297 | events.connect(events.FILE_AFTER_SAVE, function() 298 | if buffer:get_lexer() ~= "dmd" then return end 299 | buffer:annotation_clear_all() 300 | local command = M.PATH_TO_DSCANNER .. " --styleCheck " .. buffer.filename 301 | local p = os.spawn(command) 302 | local result = p:read("*a") or "" 303 | for line in result:gmatch("(.-)\r?\n") do 304 | lineNumber, column, level, message = string.match(line, "^.-%((%d+):(%d+)%)%[(%w+)%]: (.+)$") 305 | if lineNumber == nil then return end 306 | local l = tonumber(lineNumber) 307 | if l >= 0 then 308 | local c = tonumber(column) 309 | if level == "error" then 310 | buffer.annotation_style[l] = 8 311 | elseif buffer.annotation_style[l] ~= 8 then 312 | buffer.annotation_style[l] = 2 313 | end 314 | 315 | local t = buffer.annotation_text[l] 316 | if #t > 0 then 317 | buffer.annotation_text[l] = buffer.annotation_text[l] .. "\n" .. message 318 | else 319 | buffer.annotation_text[l] = message 320 | end 321 | end 322 | end 323 | end) 324 | 325 | -- Handler for clicks on the up and down arrow on function call tips 326 | events.connect(events.CALL_TIP_CLICK, function(arrow) 327 | if buffer:get_lexer() ~= "dmd" then return end 328 | if arrow == 1 then 329 | cycleCalltips(-1) 330 | elseif arrow == 2 then 331 | cycleCalltips(1) 332 | end 333 | end) 334 | 335 | if not _G.WIN32 then 336 | -- Spawn the dcd-server 337 | M.serverProcess = os.spawn(M.PATH_TO_DCD_SERVER, nil, function() end, function() end) 338 | 339 | -- Set an event handler that shuts down the DCD server, but only if this 340 | -- module successfully started it. Do nothing if somebody else owns the 341 | -- server instance 342 | events.connect(events.QUIT, function() 343 | if (M.serverProcess:status() == "running") then 344 | os.spawn(M.PATH_TO_DCD_CLIENT .. " --shutdown") 345 | _G.timeout(1, function() 346 | if (M.serverProcess:status() == "running") then 347 | M.serverProcess:kill() 348 | end 349 | end) 350 | else 351 | print('Warning: something other than us killed the DCD server') 352 | end 353 | end) 354 | end 355 | 356 | -- Key bindings 357 | keys.dmd = { 358 | ['alt+\n'] = cstyle.newline, 359 | ['shift+\n'] = cstyle.newline_semicolon, 360 | ['ctrl+;'] = cstyle.endline_semicolon, 361 | ['}'] = cstyle.match_brace_indent, 362 | ['ctrl+{'] = function() return cstyle.openBraceMagic(true) end, 363 | ['\n'] = cstyle.enter_key_pressed, 364 | ['ctrl+\n'] = autocomplete, 365 | ['ctrl+H'] = showDoc, 366 | ['down'] = function() return cycleCalltips(1) end, 367 | ['up'] = function() return cycleCalltips(-1) end, 368 | ['ctrl+G'] = M.gotoDeclaration, 369 | ['ctrl+alt+G'] = M.goBack, 370 | ['ctrl+M'] = symbolIndex, 371 | ['f7'] = function() 372 | if buffer.use_tabs then 373 | textadept.editing.filter_through(M.PATH_TO_DFMT .. " --indent_style=tab") 374 | else 375 | textadept.editing.filter_through(M.PATH_TO_DFMT .. " --indent_style=space") 376 | end 377 | end 378 | } 379 | 380 | -- Snippets 381 | if type(snippets) == 'table' then 382 | snippets.dmd = dsnippets.snippets 383 | end 384 | 385 | function M.set_buffer_properties() 386 | end 387 | 388 | return M 389 | -------------------------------------------------------------------------------- /dmd/snippets.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | M.snippets = { 4 | gpl = [[/******************************************************************************* 5 | * Authors: %1(Your name here) 6 | * Copyright: %1 7 | * Date: %[date | cut -c 5-10] %[date | cut -c 25-] 8 | * 9 | * License: 10 | * This program is free software; you can redistribute it and/or 11 | * modify it under the terms of the GNU General Public License version 12 | * 2 as published by the Free Software Foundation. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 22 | * MA 02111-1307, USA. 23 | ******************************************************************************/ 24 | 25 | %0]], 26 | 27 | gpl3 = [[/******************************************************************************* 28 | * Authors: %1(Your name here) 29 | * Copyright: %1 30 | * Date: %[date | cut -c 5-10] %[date | cut -c 25-] 31 | * 32 | * License: 33 | * This program is free software: you can redistribute it and/or modify 34 | * it under the terms of the GNU General Public License as published by 35 | * the Free Software Foundation, either version 3 of the License, or 36 | * (at your option) any later version. 37 | * 38 | * This program is distributed in the hope that it will be useful, 39 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 40 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 41 | * GNU General Public License for more details. 42 | * 43 | * You should have received a copy of the GNU General Public License 44 | * along with this program. If not, see . 45 | ******************************************************************************/ 46 | 47 | %0]], 48 | mit = [[/******************************************************************************* 49 | * The MIT License 50 | * 51 | * Copyright (c) %[date | cut -c 25-] %1(Your name here) 52 | * 53 | * Permission is hereby granted, free of charge, to any person obtaining a copy 54 | * of this software and associated documentation files (the "Software"), to deal 55 | * in the Software without restriction, including without limitation the rights 56 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 57 | * copies of the Software, and to permit persons to whom the Software is 58 | * furnished to do so, subject to the following conditions: 59 | * 60 | * The above copyright notice and this permission notice shall be included in 61 | * all copies or substantial portions of the Software. 62 | * 63 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 64 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 65 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 66 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 67 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 68 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 69 | * THE SOFTWARE. 70 | ******************************************************************************/ 71 | 72 | %0]], 73 | boost = [[/******************************************************************************* 74 | * Boost Software License - Version 1.0 - August 17th, 2003 75 | * 76 | * Permission is hereby granted, free of charge, to any person or organization 77 | * obtaining a copy of the software and accompanying documentation covered by 78 | * this license (the "Software") to use, reproduce, display, distribute, 79 | * execute, and transmit the Software, and to prepare derivative works of the 80 | * Software, and to permit third-parties to whom the Software is furnished to 81 | * do so, all subject to the following: 82 | * 83 | * The copyright notices in the Software and this entire statement, including 84 | * the above license grant, this restriction and the following disclaimer, 85 | * must be included in all copies of the Software, in whole or in part, and 86 | * all derivative works of the Software, unless such copies or derivative 87 | * works are solely in the form of machine-executable object code generated by 88 | * a source language processor. 89 | * 90 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 91 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 92 | * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 93 | * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 94 | * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 95 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 96 | * DEALINGS IN THE SOFTWARE. 97 | ******************************************************************************/ 98 | ]], 99 | banner = [[/% 100 | * %0 101 | %/]], 102 | fun = [[%1(return type) %2(name)(%3(parameters)) 103 | { 104 | %0 105 | return ; 106 | }]], 107 | vfun = [[void %1(name)(%2(parameters)) 108 | { 109 | %0 110 | }]], 111 | main = [[void main(string[] args) 112 | { 113 | %0 114 | }]], 115 | ['for'] = [[for (%1(initilization); %2(condition); %3(increment)) 116 | { 117 | %0 118 | }]], 119 | fore = [[foreach (%1(var); %2(range)) 120 | { 121 | %0 122 | }]], 123 | forei = [[foreach (%1(i); 0..%2(n)) 124 | { 125 | %0 126 | }]], 127 | forr = [[foreach (ref %1(var); %2(range)) 128 | { 129 | %0 130 | }]], 131 | fori = [[for (size_t i = 0; i != %1(condition); ++i) 132 | { 133 | %0 134 | }]], 135 | ['while'] = [[while (%1(condition)) 136 | { 137 | %0 138 | }]], 139 | ['if'] = [[if (%1(condition)) 140 | { 141 | %0 142 | }]], 143 | dw = [[do 144 | { 145 | %0 146 | } while (%1(condition));]], 147 | sw = [[switch (%1(value)) 148 | { 149 | %0 150 | default: 151 | break; 152 | }]], 153 | fsw = [[final switch (%1(value)) 154 | { 155 | %0 156 | default: 157 | break; 158 | }]], 159 | case = [[case %1: 160 | %0 161 | break;]], 162 | class = [[class %1(name) 163 | { 164 | public: 165 | 166 | private: 167 | %0 168 | }]], 169 | struct = [[struct %1(name) 170 | { 171 | %0 172 | }]], 173 | mem = 'this.%1 = %1;\n%0', 174 | dump = 'writeln("%1 = ", %1);', 175 | trace = 'writeln(__FILE__, " ", __LINE__);', 176 | wf = 'writef(%0);', 177 | wl = 'writeln(%0);', 178 | wfl = 'writefln(%0);', 179 | imp = 'import', 180 | sta = 'static', 181 | st = 'string', 182 | wch = 'wchar', 183 | dch = 'dchar', 184 | ch = 'char', 185 | dou = 'double', 186 | fl = 'float', 187 | by = 'byte', 188 | ret = 'return', 189 | im = 'immutable', 190 | co = 'const', 191 | ty = 'typeof', 192 | iit = [[if(is(typeof(%1))) 193 | { 194 | %0 195 | }]], 196 | itc = [[if(__traits(compiles, %1)) 197 | { 198 | %0 199 | }]], 200 | sif = [[static if(%1) 201 | { 202 | %0 203 | }]] 204 | } 205 | 206 | return M 207 | -------------------------------------------------------------------------------- /img/alias.xpm: -------------------------------------------------------------------------------- 1 | /* XPM */ 2 | static char * alias_xpm[] = { 3 | "16 16 17 1", 4 | " c None", 5 | ". c #547AA0", 6 | "+ c #547BA2", 7 | "@ c #547CA4", 8 | "# c #F0F0F0", 9 | "$ c #547DA6", 10 | "% c #F5F5F5", 11 | "& c #547EA8", 12 | "* c #FBFBFB", 13 | "= c #F7F7F7", 14 | "- c #F2F2F2", 15 | "; c #547BA3", 16 | "> c #ECECEC", 17 | ", c #547AA1", 18 | "' c #E7E7E7", 19 | ") c #54799F", 20 | "! c #54789D", 21 | " ", 22 | " ", 23 | " .......... ", 24 | " ++++++++++++ ", 25 | " @@@@@##@@@@@ ", 26 | " $$$$%%%%$$$$ ", 27 | " &&&&****&&&& ", 28 | " &&&==&&==&&& ", 29 | " $$$==$$==$$$ ", 30 | " @@@------@@@ ", 31 | " ;;>>>>>>>>;; ", 32 | " ,,'',,,,'',, ", 33 | " )))))))))))) ", 34 | " !!!!!!!!!! ", 35 | " ", 36 | " "}; 37 | -------------------------------------------------------------------------------- /img/class.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hackerpilot/textadept-d/c0a7cdd4de17a2194999d3c0ea2447c814bc412c/img/class.png -------------------------------------------------------------------------------- /img/class.xpm: -------------------------------------------------------------------------------- 1 | /* XPM */ 2 | static char * class_xpm[] = { 3 | "16 16 18 1", 4 | " c None", 5 | ". c #006AD6", 6 | "+ c #006DDC", 7 | "@ c #0070E2", 8 | "# c #F0F0F0", 9 | "$ c #0072E6", 10 | "% c #F5F5F5", 11 | "& c #0075EC", 12 | "* c #FBFBFB", 13 | "= c #F7F7F7", 14 | "- c #0073E8", 15 | "; c #F2F2F2", 16 | "> c #006EDE", 17 | ", c #ECECEC", 18 | "' c #006BD8", 19 | ") c #E7E7E7", 20 | "! c #0069D4", 21 | "~ c #0066CE", 22 | " ", 23 | " ", 24 | " .......... ", 25 | " ++++++++++++ ", 26 | " @@@@#####@@@ ", 27 | " $$$%%%%%%%$$ ", 28 | " &&***&&&**&& ", 29 | " &&==&&&&&&&& ", 30 | " --==-------- ", 31 | " @@;;;@@@;;@@ ", 32 | " >>>,,,,,,,>> ", 33 | " '''')))))''' ", 34 | " !!!!!!!!!!!! ", 35 | " ~~~~~~~~~~ ", 36 | " ", 37 | " "}; 38 | -------------------------------------------------------------------------------- /img/enum_dec.xpm: -------------------------------------------------------------------------------- 1 | /* XPM */ 2 | static char * enum_dec_xpm[] = { 3 | "16 16 18 1", 4 | " c None", 5 | ". c #6D43C0", 6 | "+ c #754EC3", 7 | "@ c #7751C4", 8 | "# c #F0F0F0", 9 | "$ c #7852C5", 10 | "% c #FFFFFF", 11 | "& c #F5F5F5", 12 | "* c #7D58C7", 13 | "= c #FBFBFB", 14 | "- c #FDFDFD", 15 | "; c #F7F7F7", 16 | "> c #F2F2F2", 17 | ", c #ECECEC", 18 | "' c #7048C2", 19 | ") c #E7E7E7", 20 | "! c #6A40BF", 21 | "~ c #673EBA", 22 | " ", 23 | " ", 24 | " .......... ", 25 | " ++++++++++++ ", 26 | " @@@######@@@ ", 27 | " $$$%&&&&&$$$ ", 28 | " ***==******* ", 29 | " ***-----**** ", 30 | " $$$;;;;;$$$$ ", 31 | " @@@>>@@@@@@@ ", 32 | " +++,,,,,,+++ ", 33 | " '''))))))''' ", 34 | " !!!!!!!!!!!! ", 35 | " ~~~~~~~~~~ ", 36 | " ", 37 | " "}; 38 | -------------------------------------------------------------------------------- /img/function.xpm: -------------------------------------------------------------------------------- 1 | /* XPM */ 2 | static char * function_xpm[] = { 3 | "16 16 17 1", 4 | " c None", 5 | ". c #317025", 6 | "+ c #367B28", 7 | "@ c #387F2A", 8 | "# c #F0F0F0", 9 | "$ c #FFFFFF", 10 | "% c #F5F5F5", 11 | "& c #3A832C", 12 | "* c #FBFBFB", 13 | "= c #FDFDFD", 14 | "- c #F7F7F7", 15 | "; c #F2F2F2", 16 | "> c #ECECEC", 17 | ", c #347627", 18 | "' c #E7E7E7", 19 | ") c #306D24", 20 | "! c #2F6A23", 21 | " ", 22 | " ", 23 | " .......... ", 24 | " ++++++++++++ ", 25 | " @@@######@@@ ", 26 | " @@@$%%%%%@@@ ", 27 | " &&&**&&&&&&& ", 28 | " &&&=====&&&& ", 29 | " @@@-----@@@@ ", 30 | " @@@;;@@@@@@@ ", 31 | " +++>>+++++++ ", 32 | " ,,,'',,,,,,, ", 33 | " )))))))))))) ", 34 | " !!!!!!!!!! ", 35 | " ", 36 | " "}; 37 | -------------------------------------------------------------------------------- /img/interface.xpm: -------------------------------------------------------------------------------- 1 | /* XPM */ 2 | static char * interface_xpm[] = { 3 | "16 16 19 1", 4 | " c None", 5 | ". c #CC7729", 6 | "+ c #D47D2D", 7 | "@ c #D58032", 8 | "# c #F0F0F0", 9 | "$ c #D58134", 10 | "% c #FFFFFF", 11 | "& c #F5F5F5", 12 | "* c #D6853B", 13 | "= c #FBFBFB", 14 | "- c #FDFDFD", 15 | "; c #D58236", 16 | "> c #F7F7F7", 17 | ", c #F2F2F2", 18 | "' c #ECECEC", 19 | ") c #CF792A", 20 | "! c #E7E7E7", 21 | "~ c #CA7629", 22 | "{ c #C37228", 23 | " ", 24 | " ", 25 | " .......... ", 26 | " ++++++++++++ ", 27 | " @@@######@@@ ", 28 | " $$$%&&&&&$$$ ", 29 | " *****==***** ", 30 | " *****--***** ", 31 | " ;;;;;>>;;;;; ", 32 | " @@@@@,,@@@@@ ", 33 | " +++''''''+++ ", 34 | " )))!!!!!!))) ", 35 | " ~~~~~~~~~~~~ ", 36 | " {{{{{{{{{{ ", 37 | " ", 38 | " "}; 39 | -------------------------------------------------------------------------------- /img/keyword.xpm: -------------------------------------------------------------------------------- 1 | /* XPM */ 2 | static char * keyword_xpm[] = { 3 | "16 16 24 1", 4 | " c None", 5 | ". c #B91C1C", 6 | "+ c #BA1C1C", 7 | "@ c #BE1D1D", 8 | "# c #C31E1E", 9 | "$ c #C21E1E", 10 | "% c #F0F0F0", 11 | "& c #C71E1E", 12 | "* c #F5F5F5", 13 | "= c #CC1F1F", 14 | "- c #FBFBFB", 15 | "; c #CB1F1F", 16 | "> c #CD1F1F", 17 | ", c #FDFDFD", 18 | "' c #C91F1F", 19 | ") c #F7F7F7", 20 | "! c #C41E1E", 21 | "~ c #F2F2F2", 22 | "{ c #C01D1D", 23 | "] c #ECECEC", 24 | "^ c #BB1D1D", 25 | "/ c #E7E7E7", 26 | "( c #B71C1C", 27 | "_ c #B21B1B", 28 | " ", 29 | " ", 30 | " ......+... ", 31 | " @@@@@@@@@@@@ ", 32 | " #$%%%%%%$$#$ ", 33 | " &&*******&&& ", 34 | " ==--==;---== ", 35 | " >>,,>>>>,,>> ", 36 | " ''))''''))'' ", 37 | " !!~~!!!~~~!! ", 38 | " {{]]]]]]]{{{ ", 39 | " ^^//////^^^^ ", 40 | " (((((((((((( ", 41 | " __________ ", 42 | " ", 43 | " "}; 44 | -------------------------------------------------------------------------------- /img/module.xpm: -------------------------------------------------------------------------------- 1 | /* XPM */ 2 | static char * module_xpm[] = { 3 | "16 16 14 1", 4 | " c None", 5 | ". c #000000", 6 | "+ c #000100", 7 | "@ c #FFFF83", 8 | "# c #FFFF00", 9 | "$ c #FFFF28", 10 | "% c #FFFF6A", 11 | "& c #FFFF4C", 12 | "* c #D5D500", 13 | "= c #CDCD00", 14 | "- c #A3A300", 15 | "; c #B2B200", 16 | "> c #C3C300", 17 | ", c #919100", 18 | " ", 19 | " .+ ", 20 | " .@#+ ", 21 | " .@#+ ", 22 | " .$@##+ ", 23 | " ..%@##++ ", 24 | " ..&%%@####++ ", 25 | " .@@@@@%######+ ", 26 | " +*****=-;;;;;+ ", 27 | " ++>==*;--,.. ", 28 | " ++=*;-.. ", 29 | " +>*;,. ", 30 | " +*;. ", 31 | " +*;. ", 32 | " ++ ", 33 | " "}; 34 | -------------------------------------------------------------------------------- /img/package.xpm: -------------------------------------------------------------------------------- 1 | /* XPM */ 2 | static char * package_xpm[] = { 3 | "16 16 6 1", 4 | " c None", 5 | ". c #000100", 6 | "+ c #050777", 7 | "@ c #242BAE", 8 | "# c #2E36BF", 9 | "$ c #434FE5", 10 | " ", 11 | " ............ ", 12 | " .$$$$$$$$$$$$. ", 13 | " .$##@@+$##@@+. ", 14 | " .$#@@@+$#@@@+. ", 15 | " .$@@@#+$@@@#+. ", 16 | " .$@@##+$@@##+. ", 17 | " .$+++++$+++++. ", 18 | " .$$$$$$$$$$$$. ", 19 | " .$##@@+$##@@+. ", 20 | " .$#@@@+$#@@@+. ", 21 | " .$@@@#+$@@@#+. ", 22 | " .$@@##+$@@##+. ", 23 | " .$+++++$+++++. ", 24 | " ............ ", 25 | " "}; 26 | -------------------------------------------------------------------------------- /img/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hackerpilot/textadept-d/c0a7cdd4de17a2194999d3c0ea2447c814bc412c/img/screenshot.png -------------------------------------------------------------------------------- /img/struct.xpm: -------------------------------------------------------------------------------- 1 | /* XPM */ 2 | static char * struct_xpm[] = { 3 | "16 16 19 1", 4 | " c None", 5 | ". c #000098", 6 | "+ c #00009E", 7 | "@ c #0000A2", 8 | "# c #F0F0F0", 9 | "$ c #0000A4", 10 | "% c #F5F5F5", 11 | "& c #FFFFFF", 12 | "* c #0000A8", 13 | "= c #FBFBFB", 14 | "- c #FDFDFD", 15 | "; c #0000A6", 16 | "> c #F7F7F7", 17 | ", c #F2F2F2", 18 | "' c #ECECEC", 19 | ") c #00009A", 20 | "! c #E7E7E7", 21 | "~ c #000096", 22 | "{ c #000092", 23 | " ", 24 | " ", 25 | " .......... ", 26 | " ++++++++++++ ", 27 | " @@@#######@@ ", 28 | " $$%&%%%%%%$$ ", 29 | " **===******* ", 30 | " **-------*** ", 31 | " ;;;>>>>>>>;; ", 32 | " @@@@@@@,,,@@ ", 33 | " ++''''''''++ ", 34 | " ))!!!!!!!))) ", 35 | " ~~~~~~~~~~~~ ", 36 | " {{{{{{{{{{ ", 37 | " ", 38 | " "}; 39 | -------------------------------------------------------------------------------- /img/template.xpm: -------------------------------------------------------------------------------- 1 | /* XPM */ 2 | static char * template_xpm[] = { 3 | "16 16 14 1", 4 | " c None", 5 | ". c #00A2A4", 6 | "+ c #00A9AB", 7 | "@ c #E1FFFF", 8 | "# c #EBFFFF", 9 | "$ c #F7FFFF", 10 | "% c #FBFFFF", 11 | "& c #EFFFFF", 12 | "* c #E5FFFF", 13 | "= c #D9FFFF", 14 | "- c #00A5A7", 15 | "; c #CFFEFF", 16 | "> c #00A0A3", 17 | ", c #009A9C", 18 | " ", 19 | " ", 20 | " .......... ", 21 | " ++++++++++++ ", 22 | " +++@@@@@@+++ ", 23 | " +++######+++ ", 24 | " +++++$$+++++ ", 25 | " +++++%%+++++ ", 26 | " +++++&&+++++ ", 27 | " +++++**+++++ ", 28 | " +++++==+++++ ", 29 | " -----;;----- ", 30 | " >>>>>>>>>>>> ", 31 | " ,,,,,,,,,, ", 32 | " ", 33 | " "}; 34 | -------------------------------------------------------------------------------- /img/union.xpm: -------------------------------------------------------------------------------- 1 | /* XPM */ 2 | static char * union_xpm[] = { 3 | "16 16 18 1", 4 | " c None", 5 | ". c #A06B35", 6 | "+ c #A87038", 7 | "@ c #AC7339", 8 | "# c #F7EFE7", 9 | "$ c #AF753A", 10 | "% c #F9F4EE", 11 | "& c #B3783C", 12 | "* c #FCFAF7", 13 | "= c #FDFBF8", 14 | "- c #B1763B", 15 | "; c #FAF5F0", 16 | "> c #F8F1EA", 17 | ", c #A97138", 18 | "' c #F4EBE1", 19 | ") c #A36D36", 20 | "! c #F2E6D9", 21 | "~ c #9C6833", 22 | " ", 23 | " ", 24 | " .......... ", 25 | " ++++++++++++ ", 26 | " @@##@@@@##@@ ", 27 | " $$%%$$$$%%$$ ", 28 | " &&**&&&&**&& ", 29 | " &&==&&&&==&& ", 30 | " --;;----;;-- ", 31 | " @@>>@@@@>>@@ ", 32 | " ,,'''''''',, ", 33 | " )))!!!!!!))) ", 34 | " ............ ", 35 | " ~~~~~~~~~~ ", 36 | " ", 37 | " "}; 38 | -------------------------------------------------------------------------------- /img/variable.xpm: -------------------------------------------------------------------------------- 1 | /* XPM */ 2 | static char * variable_xpm[] = { 3 | "16 16 18 1", 4 | " c None", 5 | ". c #933093", 6 | "+ c #A035A0", 7 | "@ c #A537A5", 8 | "# c #FFFFFF", 9 | "$ c #F0F0F0", 10 | "% c #A637A6", 11 | "& c #F5F5F5", 12 | "* c #AC39AC", 13 | "= c #FBFBFB", 14 | "- c #FDFDFD", 15 | "; c #F7F7F7", 16 | "> c #F2F2F2", 17 | ", c #ECECEC", 18 | "' c #9A339A", 19 | ") c #E7E7E7", 20 | "! c #8E2F8E", 21 | "~ c #8B2E8B", 22 | " ", 23 | " ", 24 | " .......... ", 25 | " ++++++++++++ ", 26 | " @@#$@@@@$$@@ ", 27 | " %%&#%%%%&&%% ", 28 | " **==****==** ", 29 | " ***--**--*** ", 30 | " %%%;;%%;;%%% ", 31 | " @@@@>>>>@@@@ ", 32 | " ++++,,,,++++ ", 33 | " '''''))''''' ", 34 | " !!!!!!!!!!!! ", 35 | " ~~~~~~~~~~ ", 36 | " ", 37 | " "}; 38 | --------------------------------------------------------------------------------