├── .gitignore
├── .travis.yml
├── CMakeLists.txt
├── LICENSE.MIT
├── README.md
├── example
├── CMakeLists.txt
├── image
│ └── preview.png
├── include
│ └── MainWindow.hpp
├── resources
│ ├── code_samples
│ │ ├── cxx.cpp
│ │ ├── json.json
│ │ ├── lua.lua
│ │ ├── python.py
│ │ ├── shader.glsl
│ │ └── xml.xml
│ ├── demo_resources.qrc
│ └── styles
│ │ └── drakula.xml
└── src
│ ├── MainWindow.cpp
│ └── main.cpp
├── include
├── QCXXHighlighter
├── QCodeEditor
├── QFramedTextAttribute
├── QGLSLCompleter
├── QGLSLHighlighter
├── QHighlightBlockRule
├── QHighlightRule
├── QJSONHighlighter
├── QLanguage
├── QLineNumberArea
├── QLuaCompleter
├── QLuaHighlighter
├── QPythonCompleter
├── QPythonHighlighter
├── QStyleSyntaxHighlighter
├── QSyntaxStyle
├── QXMLHighlighter
└── internal
│ ├── QCXXHighlighter.hpp
│ ├── QCodeEditor.hpp
│ ├── QFramedTextAttribute.hpp
│ ├── QGLSLCompleter.hpp
│ ├── QGLSLHighlighter.hpp
│ ├── QHighlightBlockRule.hpp
│ ├── QHighlightRule.hpp
│ ├── QJSONHighlighter.hpp
│ ├── QLanguage.hpp
│ ├── QLineNumberArea.hpp
│ ├── QLuaCompleter.hpp
│ ├── QLuaHighlighter.hpp
│ ├── QPythonCompleter.hpp
│ ├── QPythonHighlighter.hpp
│ ├── QStyleSyntaxHighlighter.hpp
│ ├── QSyntaxStyle.hpp
│ └── QXMLHighlighter.hpp
├── resources
├── default_style.xml
├── languages
│ ├── cpp.xml
│ ├── glsl.xml
│ ├── lua.xml
│ └── python.xml
└── qcodeeditor_resources.qrc
└── src
└── internal
├── QCXXHighlighter.cpp
├── QCodeEditor.cpp
├── QFramedTextAttribute.cpp
├── QGLSLCompleter.cpp
├── QGLSLHighlighter.cpp
├── QJSONHighlighter.cpp
├── QLanguage.cpp
├── QLineNumberArea.cpp
├── QLuaCompleter.cpp
├── QLuaHighlighter.cpp
├── QPythonCompleter.cpp
├── QPythonHighlighter.cpp
├── QStyleSyntaxHighlighter.cpp
├── QSyntaxStyle.cpp
└── QXMLHighlighter.cpp
/.gitignore:
--------------------------------------------------------------------------------
1 | cmake-build-debug/
2 | cmake-build-release/
3 | .idea/
4 | *~
5 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | dist: bionic
2 | language: cpp
3 | sudo: required
4 |
5 | notifications:
6 | email:
7 | on_success: never
8 | on_failure: always
9 |
10 | addons:
11 | apt:
12 | sources:
13 | - sourceline: 'ppa:beineri/opt-qt-5.12.0-bionic'
14 | packages:
15 | - cmake
16 | - cmake-data
17 | - qt512-meta-full
18 | - libgl-dev
19 |
20 | compiler:
21 | - gcc
22 | - clang
23 |
24 | script:
25 | - |
26 | . /opt/qt512/bin/qt512-env.sh
27 | mkdir build
28 | cmake -B$TRAVIS_BUILD_DIR/build -H$TRAVIS_BUILD_DIR
29 | cmake --build "$TRAVIS_BUILD_DIR/build" --target all -- -j4
30 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.6)
2 | project(QCodeEditor)
3 |
4 | set(CMAKE_CXX_STANDARD 11)
5 |
6 | option(BUILD_EXAMPLE "Example building required" Off)
7 |
8 | if (${BUILD_EXAMPLE})
9 | message(STATUS "QCodeEditor example will be built.")
10 | add_subdirectory(example)
11 | endif()
12 |
13 | set(RESOURCES_FILE
14 | resources/qcodeeditor_resources.qrc
15 | )
16 |
17 | set(INCLUDE_FILES
18 | include/QHighlightRule
19 | include/QHighlightBlockRule
20 | include/QCodeEditor
21 | include/QCXXHighlighter
22 | include/QLineNumberArea
23 | include/QStyleSyntaxHighlighter
24 | include/QSyntaxStyle
25 | include/QGLSLCompleter
26 | include/QGLSLHighlighter
27 | include/QLanguage
28 | include/QXMLHighlighter
29 | include/QJSONHighlighter
30 | include/QLuaCompleter
31 | include/QLuaHighlighter
32 | include/QPythonHighlighter
33 | include/QFramedTextAttribute
34 | include/internal/QHighlightRule.hpp
35 | include/internal/QHighlightBlockRule.hpp
36 | include/internal/QCodeEditor.hpp
37 | include/internal/QCXXHighlighter.hpp
38 | include/internal/QLineNumberArea.hpp
39 | include/internal/QStyleSyntaxHighlighter.hpp
40 | include/internal/QSyntaxStyle.hpp
41 | include/internal/QGLSLCompleter.hpp
42 | include/internal/QGLSLHighlighter.hpp
43 | include/internal/QLanguage.hpp
44 | include/internal/QXMLHighlighter.hpp
45 | include/internal/QJSONHighlighter.hpp
46 | include/internal/QLuaCompleter.hpp
47 | include/internal/QLuaHighlighter.hpp
48 | include/internal/QPythonCompleter.hpp
49 | include/internal/QPythonHighlighter.hpp
50 | include/internal/QFramedTextAttribute.hpp
51 | )
52 |
53 | set(SOURCE_FILES
54 | src/internal/QCodeEditor.cpp
55 | src/internal/QLineNumberArea.cpp
56 | src/internal/QCXXHighlighter.cpp
57 | src/internal/QSyntaxStyle.cpp
58 | src/internal/QStyleSyntaxHighlighter.cpp
59 | src/internal/QGLSLCompleter.cpp
60 | src/internal/QGLSLHighlighter.cpp
61 | src/internal/QLanguage.cpp
62 | src/internal/QXMLHighlighter.cpp
63 | src/internal/QJSONHighlighter.cpp
64 | src/internal/QLuaCompleter.cpp
65 | src/internal/QLuaHighlighter.cpp
66 | src/internal/QPythonCompleter.cpp
67 | src/internal/QPythonHighlighter.cpp
68 | src/internal/QFramedTextAttribute.cpp
69 | )
70 |
71 | # Create code for QObjects
72 | set(CMAKE_AUTOMOC On)
73 |
74 | # Create code from resource files
75 | set(CMAKE_AUTORCC ON)
76 |
77 | # Find includes in corresponding build directories
78 | find_package(Qt5Core CONFIG REQUIRED)
79 | find_package(Qt5Widgets CONFIG REQUIRED)
80 | find_package(Qt5Gui CONFIG REQUIRED)
81 |
82 | add_library(QCodeEditor STATIC
83 | ${RESOURCES_FILE}
84 | ${SOURCE_FILES}
85 | ${INCLUDE_FILES}
86 | )
87 |
88 | target_include_directories(QCodeEditor PUBLIC
89 | include
90 | )
91 |
92 | if(CMAKE_COMPILER_IS_GNUCXX)
93 | target_compile_options(QCodeEditor
94 | PRIVATE
95 | -ansi
96 | -pedantic
97 | -Wall
98 | -Wextra
99 | -Weffc++
100 | -Woverloaded-virtual
101 | -Winit-self
102 | -Wunreachable-code
103 | )
104 | endif(CMAKE_COMPILER_IS_GNUCXX)
105 |
106 | target_link_libraries(QCodeEditor
107 | Qt5::Core
108 | Qt5::Widgets
109 | Qt5::Gui
110 | )
111 |
--------------------------------------------------------------------------------
/LICENSE.MIT:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2013-2019 Megaxela
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.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Qt Code Editor Widget
2 | It's a widget for editing/viewing code.
3 |
4 | This project uses a resource named `qcodeeditor_resources.qrc`. The main application
5 | must not use a resource file with the same name.
6 |
7 | (It's not a project from a Qt example.)
8 |
9 | ## Requirements
10 | 0. C++11 featured compiler.
11 | 0. Qt 5.
12 |
13 | ## Abilities
14 | 1. Auto parentheses.
15 | 1. Different highlight rules.
16 | 1. Auto indentation.
17 | 1. Replace tabs with spaces.
18 | 1. GLSL completion rules.
19 | 1. GLSL highlight rules.
20 | 1. C++ highlight rules.
21 | 1. XML highlight rules.
22 | 1. JSON highligh rules.
23 | 1. Frame selection.
24 | 1. Qt Creator styles.
25 |
26 | ## Build
27 | It's a CMake-based library, so it can be used as a submodule (see the example).
28 | But here are the steps to build it as a static library (for external use for example).
29 |
30 | 1. Clone the repository: `git clone https://github.com/Megaxela/QCodeEditor`
31 | 1. Go into the repository: `cd QCodeEditor`
32 | 1. Create a build folder: `mkdir build`
33 | 1. Go into the build folder: `cd build`
34 | 1. Generate a build file for your compiler: `cmake ..`
35 | 1. If you need to build the example, specify `-DBUILD_EXAMPLE=On` on this step.
36 | 1. Build the library: `cmake --build .`
37 |
38 | ## Example
39 |
40 | By default, `QCodeEditor` uses the standard QtCreator theme. But you may specify
41 | your own by parsing it with `QSyntaxStyle`. The example uses [Dracula](https://draculatheme.com) theme.
42 | (See the example for more.)
43 |
44 |
45 |
46 | ## LICENSE
47 |
48 |
49 |
50 | Library is licensed under the [MIT License](https://opensource.org/licenses/MIT)
51 |
52 | Permission is hereby granted, free of charge, to any person obtaining a copy
53 | of this software and associated documentation files (the "Software"), to deal
54 | in the Software without restriction, including without limitation the rights
55 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
56 | copies of the Software, and to permit persons to whom the Software is
57 | furnished to do so, subject to the following conditions:
58 |
59 | The above copyright notice and this permission notice shall be included in all
60 | copies or substantial portions of the Software.
61 |
62 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
63 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
64 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
65 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
66 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
67 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
68 | SOFTWARE.
69 |
--------------------------------------------------------------------------------
/example/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.6)
2 | project(QCodeEditorExample)
3 |
4 | set(CMAKE_CXX_STANDARD 17)
5 |
6 | set(CMAKE_AUTOMOC On)
7 | set(CMAKE_AUTORCC ON)
8 |
9 | find_package(Qt5Core CONFIG REQUIRED)
10 | find_package(Qt5Widgets CONFIG REQUIRED)
11 | find_package(Qt5Gui CONFIG REQUIRED)
12 |
13 | add_executable(QCodeEditorExample
14 | resources/demo_resources.qrc
15 | src/main.cpp
16 | src/MainWindow.cpp
17 | include/MainWindow.hpp
18 | )
19 |
20 | target_include_directories(QCodeEditorExample PUBLIC
21 | include
22 | )
23 |
24 | target_link_libraries(QCodeEditorExample
25 | Qt5::Core
26 | Qt5::Widgets
27 | Qt5::Gui
28 | QCodeEditor
29 | )
--------------------------------------------------------------------------------
/example/image/preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Megaxela/QCodeEditor/dc644d41b68978ab9a5591ba891a223221570e74/example/image/preview.png
--------------------------------------------------------------------------------
/example/include/MainWindow.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | // Qt
4 | #include // Required for inheritance
5 | #include
6 | #include
7 | #include
8 |
9 | class QVBoxLayout;
10 | class QSyntaxStyle;
11 | class QComboBox;
12 | class QCheckBox;
13 | class QSpinBox;
14 | class QCompleter;
15 | class QStyleSyntaxHighlighter;
16 | class QCodeEditor;
17 |
18 | /**
19 | * @brief Class, that describes demo main window.
20 | */
21 | class MainWindow : public QMainWindow
22 | {
23 | Q_OBJECT
24 |
25 | public:
26 |
27 | /**
28 | * @brief Constructor.
29 | * @param parent Pointer to parent widget.
30 | */
31 | explicit MainWindow(QWidget* parent=nullptr);
32 |
33 | private:
34 |
35 | void loadStyle(QString path);
36 |
37 | QString loadCode(QString path);
38 |
39 | void initData();
40 |
41 | void createWidgets();
42 |
43 | void setupWidgets();
44 |
45 | void performConnections();
46 |
47 | QVBoxLayout* m_setupLayout;
48 |
49 | QComboBox* m_codeSampleCombobox;
50 | QComboBox* m_highlighterCombobox;
51 | QComboBox* m_completerCombobox;
52 | QComboBox* m_styleCombobox;
53 |
54 | QCheckBox* m_readOnlyCheckBox;
55 | QCheckBox* m_wordWrapCheckBox;
56 | QCheckBox* m_parenthesesEnabledCheckbox;
57 | QCheckBox* m_tabReplaceEnabledCheckbox;
58 | QSpinBox* m_tabReplaceNumberSpinbox;
59 | QCheckBox* m_autoIndentationCheckbox;
60 |
61 | QCodeEditor* m_codeEditor;
62 |
63 | QVector> m_codeSamples;
64 | QVector> m_completers;
65 | QVector> m_highlighters;
66 | QVector> m_styles;
67 | };
68 |
69 |
--------------------------------------------------------------------------------
/example/resources/code_samples/cxx.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int main()
4 | {
5 | int n, sum = 0;
6 |
7 | std::cout << "Enter a positive integer: ";
8 | std::cin >> n;
9 |
10 | for (int i = 1; i <= n; ++i)
11 | {
12 | sum += i;
13 | }
14 |
15 | std::cout << "Sum = " << sum;
16 | return 0;
17 | }
--------------------------------------------------------------------------------
/example/resources/code_samples/json.json:
--------------------------------------------------------------------------------
1 | {
2 | "root": {
3 | "some array": [1, 2, 3],
4 | "some string": "Hello world",
5 | "some dbl": 2.121323,
6 | "some bool": true,
7 | "some null": null
8 | }
9 | }
--------------------------------------------------------------------------------
/example/resources/code_samples/lua.lua:
--------------------------------------------------------------------------------
1 | -- Two dashes start a one-line comment.
2 | --[[
3 | Adding two ['s and ]'s makes it a
4 | multi-line comment.
5 | --]]
6 |
7 | ----------------------------------------------------
8 | -- 1. Variables and flow control.
9 | ----------------------------------------------------
10 |
11 | num = 42 -- All numbers are doubles.
12 | -- Don't freak out, 64-bit doubles have 52 bits for
13 | -- storing exact int values; machine precision is
14 | -- not a problem for ints that need < 52 bits.
15 |
16 | s = 'walternate' -- Immutable strings like Python.
17 | t = "double-quotes are also fine"
18 | u = [[ Double brackets
19 | start and end
20 | multi-line strings.]]
21 | t = nil -- Undefines t; Lua has garbage collection.
22 |
23 | -- Blocks are denoted with keywords like do/end:
24 | while num < 50 do
25 | num = num + 1 -- No ++ or += type operators.
26 | end
27 |
28 | -- If clauses:
29 | if num > 40 then
30 | print('over 40')
31 | elseif s ~= 'walternate' then -- ~= is not equals.
32 | -- Equality check is == like Python; ok for strs.
33 | io.write('not over 40\n') -- Defaults to stdout.
34 | else
35 | -- Variables are global by default.
36 | thisIsGlobal = 5 -- Camel case is common.
37 |
38 | -- How to make a variable local:
39 | local line = io.read() -- Reads next stdin line.
40 |
41 | -- String concatenation uses the .. operator:
42 | print('Winter is coming, ' .. line)
43 | end
44 |
45 | -- Undefined variables return nil.
46 | -- This is not an error:
47 | foo = anUnknownVariable -- Now foo = nil.
48 |
49 | aBoolValue = false
50 |
51 | -- Only nil and false are falsy; 0 and '' are true!
52 | if not aBoolValue then print('twas false') end
53 |
54 | -- 'or' and 'and' are short-circuited.
55 | -- This is similar to the a?b:c operator in C/js:
56 | ans = aBoolValue and 'yes' or 'no' --> 'no'
57 |
58 | karlSum = 0
59 | for i = 1, 100 do -- The range includes both ends.
60 | karlSum = karlSum + i
61 | end
62 |
63 | -- Use "100, 1, -1" as the range to count down:
64 | fredSum = 0
65 | for j = 100, 1, -1 do fredSum = fredSum + j end
66 |
67 | -- In general, the range is begin, end[, step].
68 |
69 | -- Another loop construct:
70 | repeat
71 | print('the way of the future')
72 | num = num - 1
73 | until num == 0
74 |
75 |
76 | ----------------------------------------------------
77 | -- 2. Functions.
78 | ----------------------------------------------------
79 |
80 | function fib(n)
81 | if n < 2 then return 1 end
82 | return fib(n - 2) + fib(n - 1)
83 | end
84 |
85 | -- Closures and anonymous functions are ok:
86 | function adder(x)
87 | -- The returned function is created when adder is
88 | -- called, and remembers the value of x:
89 | return function (y) return x + y end
90 | end
91 | a1 = adder(9)
92 | a2 = adder(36)
93 | print(a1(16)) --> 25
94 | print(a2(64)) --> 100
95 |
96 | -- Returns, func calls, and assignments all work
97 | -- with lists that may be mismatched in length.
98 | -- Unmatched receivers are nil;
99 | -- unmatched senders are discarded.
100 |
101 | x, y, z = 1, 2, 3, 4
102 | -- Now x = 1, y = 2, z = 3, and 4 is thrown away.
103 |
104 | function bar(a, b, c)
105 | print(a, b, c)
106 | return 4, 8, 15, 16, 23, 42
107 | end
108 |
109 | x, y = bar('zaphod') --> print zaphod nil nil
110 | -- Now x = 4, y = 8, values 15..42 are discarded.
111 |
112 | -- Functions are first-class, may be local/global.
113 | -- These are the same:
114 | function f(x) return x * x end
115 | f = function (x) return x * x end
116 |
117 | -- And so are these:
118 | local function g(x) return math.sin(x) end
119 | local g; g = function (x) return math.sin(x) end
120 | -- the 'local g' decl makes g-self-references ok.
121 |
122 | -- Trig funcs work in radians, by the way.
123 |
124 | -- Calls with one string param don't need parens:
125 | print 'hello' -- Works fine.
126 |
127 |
128 | ----------------------------------------------------
129 | -- 3. Tables.
130 | ----------------------------------------------------
131 |
132 | -- Tables = Lua's only compound data structure;
133 | -- they are associative arrays.
134 | -- Similar to php arrays or js objects, they are
135 | -- hash-lookup dicts that can also be used as lists.
136 |
137 | -- Using tables as dictionaries / maps:
138 |
139 | -- Dict literals have string keys by default:
140 | t = {key1 = 'value1', key2 = false}
141 |
142 | -- String keys can use js-like dot notation:
143 | print(t.key1) -- Prints 'value1'.
144 | t.newKey = {} -- Adds a new key/value pair.
145 | t.key2 = nil -- Removes key2 from the table.
146 |
147 | -- Literal notation for any (non-nil) value as key:
148 | u = {['@!#'] = 'qbert', [{}] = 1729, [6.28] = 'tau'}
149 | print(u[6.28]) -- prints tau
150 |
151 | -- Key matching is basically by value for numbers
152 | -- and strings, but by identity for tables.
153 | a = u['@!#'] -- Now a = 'qbert'.
154 | b = u[{}] -- We might expect 1729, but it's nil:
155 | -- b = nil since the lookup fails. It fails
156 | -- because the key we used is not the same object
157 | -- as the one used to store the original value. So
158 | -- strings & numbers are more portable keys.
159 |
160 | -- A one-table-param function call needs no parens:
161 | function h(x) print(x.key1) end
162 | h{key1 = 'Sonmi~451'} -- Prints 'Sonmi~451'.
163 |
164 | for key, val in pairs(u) do -- Table iteration.
165 | print(key, val)
166 | end
167 |
168 | -- _G is a special table of all globals.
169 | print(_G['_G'] == _G) -- Prints 'true'.
170 |
171 | -- Using tables as lists / arrays:
172 |
173 | -- List literals implicitly set up int keys:
174 | v = {'value1', 'value2', 1.21, 'gigawatts'}
175 | for i = 1, #v do -- #v is the size of v for lists.
176 | print(v[i]) -- Indices start at 1 !! SO CRAZY!
177 | end
178 | -- A 'list' is not a real type. v is just a table
179 | -- with consecutive integer keys, treated as a list.
180 |
181 | ----------------------------------------------------
182 | -- 3.1 Metatables and metamethods.
183 | ----------------------------------------------------
184 |
185 | -- A table can have a metatable that gives the table
186 | -- operator-overloadish behavior. Later we'll see
187 | -- how metatables support js-prototypey behavior.
188 |
189 | f1 = {a = 1, b = 2} -- Represents the fraction a/b.
190 | f2 = {a = 2, b = 3}
191 |
192 | -- This would fail:
193 | -- s = f1 + f2
194 |
195 | metafraction = {}
196 | function metafraction.__add(f1, f2)
197 | sum = {}
198 | sum.b = f1.b * f2.b
199 | sum.a = f1.a * f2.b + f2.a * f1.b
200 | return sum
201 | end
202 |
203 | setmetatable(f1, metafraction)
204 | setmetatable(f2, metafraction)
205 |
206 | s = f1 + f2 -- call __add(f1, f2) on f1's metatable
207 |
208 | -- f1, f2 have no key for their metatable, unlike
209 | -- prototypes in js, so you must retrieve it as in
210 | -- getmetatable(f1). The metatable is a normal table
211 | -- with keys that Lua knows about, like __add.
212 |
213 | -- But the next line fails since s has no metatable:
214 | -- t = s + s
215 | -- Class-like patterns given below would fix this.
216 |
217 | -- An __index on a metatable overloads dot lookups:
218 | defaultFavs = {animal = 'gru', food = 'donuts'}
219 | myFavs = {food = 'pizza'}
220 | setmetatable(myFavs, {__index = defaultFavs})
221 | eatenBy = myFavs.animal -- works! thanks, metatable
222 |
223 | -- Direct table lookups that fail will retry using
224 | -- the metatable's __index value, and this recurses.
225 |
226 | -- An __index value can also be a function(tbl, key)
227 | -- for more customized lookups.
228 |
229 | -- Values of __index,add, .. are called metamethods.
230 | -- Full list. Here a is a table with the metamethod.
231 |
232 | -- __add(a, b) for a + b
233 | -- __sub(a, b) for a - b
234 | -- __mul(a, b) for a * b
235 | -- __div(a, b) for a / b
236 | -- __mod(a, b) for a % b
237 | -- __pow(a, b) for a ^ b
238 | -- __unm(a) for -a
239 | -- __concat(a, b) for a .. b
240 | -- __len(a) for #a
241 | -- __eq(a, b) for a == b
242 | -- __lt(a, b) for a < b
243 | -- __le(a, b) for a <= b
244 | -- __index(a, b) for a.b
245 | -- __newindex(a, b, c) for a.b = c
246 | -- __call(a, ...) for a(...)
247 |
248 | ----------------------------------------------------
249 | -- 3.2 Class-like tables and inheritance.
250 | ----------------------------------------------------
251 |
252 | -- Classes aren't built in; there are different ways
253 | -- to make them using tables and metatables.
254 |
255 | -- Explanation for this example is below it.
256 |
257 | Dog = {} -- 1.
258 |
259 | function Dog:new() -- 2.
260 | newObj = {sound = 'woof'} -- 3.
261 | self.__index = self -- 4.
262 | return setmetatable(newObj, self) -- 5.
263 | end
264 |
265 | function Dog:makeSound() -- 6.
266 | print('I say ' .. self.sound)
267 | end
268 |
269 | mrDog = Dog:new() -- 7.
270 | mrDog:makeSound() -- 'I say woof' -- 8.
271 |
272 | -- 1. Dog acts like a class; it's really a table.
273 | -- 2. function tablename:fn(...) is the same as
274 | -- function tablename.fn(self, ...)
275 | -- The : just adds a first arg called self.
276 | -- Read 7 & 8 below for how self gets its value.
277 | -- 3. newObj will be an instance of class Dog.
278 | -- 4. self = the class being instantiated. Often
279 | -- self = Dog, but inheritance can change it.
280 | -- newObj gets self's functions when we set both
281 | -- newObj's metatable and self's __index to self.
282 | -- 5. Reminder: setmetatable returns its first arg.
283 | -- 6. The : works as in 2, but this time we expect
284 | -- self to be an instance instead of a class.
285 | -- 7. Same as Dog.new(Dog), so self = Dog in new().
286 | -- 8. Same as mrDog.makeSound(mrDog); self = mrDog.
287 |
288 | ----------------------------------------------------
289 |
290 | -- Inheritance example:
291 |
292 | LoudDog = Dog:new() -- 1.
293 |
294 | function LoudDog:makeSound()
295 | s = self.sound .. ' ' -- 2.
296 | print(s .. s .. s)
297 | end
298 |
299 | seymour = LoudDog:new() -- 3.
300 | seymour:makeSound() -- 'woof woof woof' -- 4.
301 |
302 | -- 1. LoudDog gets Dog's methods and variables.
303 | -- 2. self has a 'sound' key from new(), see 3.
304 | -- 3. Same as LoudDog.new(LoudDog), and converted to
305 | -- Dog.new(LoudDog) as LoudDog has no 'new' key,
306 | -- but does have __index = Dog on its metatable.
307 | -- Result: seymour's metatable is LoudDog, and
308 | -- LoudDog.__index = LoudDog. So seymour.key will
309 | -- = seymour.key, LoudDog.key, Dog.key, whichever
310 | -- table is the first with the given key.
311 | -- 4. The 'makeSound' key is found in LoudDog; this
312 | -- is the same as LoudDog.makeSound(seymour).
313 |
314 | -- If needed, a subclass's new() is like the base's:
315 | function LoudDog:new()
316 | newObj = {}
317 | -- set up newObj
318 | self.__index = self
319 | return setmetatable(newObj, self)
320 | end
321 |
322 | ----------------------------------------------------
323 | -- 4. Modules.
324 | ----------------------------------------------------
325 |
326 |
327 | --[[ I'm commenting out this section so the rest of
328 | -- this script remains runnable.
329 | -- Suppose the file mod.lua looks like this:
330 | local M = {}
331 |
332 | local function sayMyName()
333 | print('Hrunkner')
334 | end
335 |
336 | function M.sayHello()
337 | print('Why hello there')
338 | sayMyName()
339 | end
340 |
341 | return M
342 |
343 | -- Another file can use mod.lua's functionality:
344 | local mod = require('mod') -- Run the file mod.lua.
345 |
346 | -- require is the standard way to include modules.
347 | -- require acts like: (if not cached; see below)
348 | local mod = (function ()
349 |
350 | end)()
351 | -- It's like mod.lua is a function body, so that
352 | -- locals inside mod.lua are invisible outside it.
353 |
354 | -- This works because mod here = M in mod.lua:
355 | mod.sayHello() -- Says hello to Hrunkner.
356 |
357 | -- This is wrong; sayMyName only exists in mod.lua:
358 | mod.sayMyName() -- error
359 |
360 | -- require's return values are cached so a file is
361 | -- run at most once, even when require'd many times.
362 |
363 | -- Suppose mod2.lua contains print('Hi!').
364 | local a = require('mod2') -- Prints Hi!
365 | local b = require('mod2') -- Doesn't print; a=b.
366 |
367 | -- dofile is like require without caching:
368 | dofile('mod2.lua') --> Hi!
369 | dofile('mod2.lua') --> Hi! (runs it again)
370 |
371 | -- loadfile loads a lua file but doesn't run it yet.
372 | f = loadfile('mod2.lua') -- Call f() to run it.
373 |
374 | -- loadstring is loadfile for strings.
375 | g = loadstring('print(343)') -- Returns a function.
376 | g() -- Prints out 343; nothing printed before now.
377 |
378 | --]]
379 |
380 | ----------------------------------------------------
381 | -- 5. References.
382 | ----------------------------------------------------
383 |
384 | --[[
385 |
386 | I was excited to learn Lua so I could make games
387 | with the Löve 2D game engine. That's the why.
388 |
389 | I started with BlackBulletIV's Lua for programmers.
390 | Next I read the official Programming in Lua book.
391 | That's the how.
392 |
393 | It might be helpful to check out the Lua short
394 | reference on lua-users.org.
395 |
396 | The main topics not covered are standard libraries:
397 | * string library
398 | * table library
399 | * math library
400 | * io library
401 | * os library
402 |
403 | By the way, this entire file is valid Lua; save it
404 | as learn.lua and run it with "lua learn.lua" !
405 |
406 | This was first written for tylerneylon.com. It's
407 | also available as a github gist. Tutorials for other
408 | languages, in the same style as this one, are here:
409 |
410 | http://learnxinyminutes.com/
411 |
412 | Have fun with Lua!
413 |
414 | --]]
--------------------------------------------------------------------------------
/example/resources/code_samples/python.py:
--------------------------------------------------------------------------------
1 | import numpy
2 |
3 | def sqr_array(x):
4 | '''
5 | Documentation for sqr_array.
6 | A multi line string!'
7 | '''
8 |
9 | return np.array(x)**2
10 |
11 | s = 'this is a string'
12 | d = 10
13 | x = np.arange(0,d,d/10)
14 | y = sqr_array(x)
15 |
--------------------------------------------------------------------------------
/example/resources/code_samples/shader.glsl:
--------------------------------------------------------------------------------
1 | precision mediump float;
2 |
3 | uniform vec2 resolution;
4 | uniform float time;
5 |
6 | vec3 trans(vec3 p)
7 | {
8 | return mod(p, 8.0)-4.0;
9 | }
10 |
11 | float distanceFunction(vec3 pos)
12 | {
13 | return length(trans(pos)) - 1.5;
14 | }
15 |
16 | vec3 getNormal(vec3 p)
17 | {
18 | const float d = 0.0001;
19 | return
20 | normalize
21 | (
22 | vec3
23 | (
24 | distanceFunction(p+vec3(d, 0.0, 0))-distanceFunction(p+vec3(-d,0.0,0.0)),
25 | distanceFunction(p+vec3(0.0, d, 0.0))-distanceFunction(p+vec3(0.0,-d,0.0)),
26 | distanceFunction(p+vec3(0.0, 0.0, d))-distanceFunction(p+vec3(0.0,0.0,-d))
27 | )
28 | );
29 | }
30 |
31 | void main() {
32 | vec2 pos = (gl_FragCoord.xy*2.0 -resolution) / resolution.y;
33 |
34 | vec3 camPos = vec3(0.0, 0.0, 3.0);
35 | vec3 camDir = vec3(0.0, 0.0, -1.0);
36 | vec3 camUp = vec3(0.0, 1.0, 0.0);
37 | vec3 camSide = cross(camDir, camUp);
38 | float focus = sin(time)*1.5+4.0;
39 |
40 | mat3 lense = mat3(1.,0.,0.,
41 | 0.,888989898989898989,0.,
42 | 0.,0.,1.);
43 | vec3 pos3 = vec3(pos,camDir.z*10.);
44 | camDir = vec3(
45 | camDir.x,
46 | camDir.y,
47 | camDir.z);
48 | camDir*=normalize(dot(camDir,pos3));
49 | vec3 rayDir = normalize(camSide*pos.x + camUp*pos.y + camDir*focus);
50 |
51 | float t = 0.0, d;
52 | vec3 posOnRay = camPos;
53 |
54 | for(int i=0; i<64; ++i)
55 | {
56 | d = distanceFunction(posOnRay);
57 | t += d;
58 | posOnRay = camPos + t*rayDir;
59 | }
60 |
61 | vec3 normal = getNormal(posOnRay);
62 | if(abs(d) < 0.001)
63 | {
64 | gl_FragColor = vec4(normal, 1.0);
65 | }else
66 | {
67 | gl_FragColor = vec4(0.0);
68 | }
69 | }
--------------------------------------------------------------------------------
/example/resources/code_samples/xml.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Joe
7 | Bob
8 | Trenton Literary Review Honorable Mention
9 |
10 | 12
11 |
12 |
13 |
14 | Mary
15 | Bob
16 | Selected Short Stories of
17 | Mary
18 | Bob
19 |
20 |
21 |
22 | Britney
23 | Bob
24 |
25 | 55
26 |
27 |
28 | 2.50
29 |
30 |
31 |
32 |
33 | Toni
34 | Bob
35 | B.A.
36 | Ph.D.
37 | Pulitzer
38 | Still in Trenton
39 | Trenton Forever
40 |
41 | 6.50
42 |
43 |
It was a dark and stormy night.
44 |
But then all nights in Trenton seem dark and
45 | stormy to someone who has gone through what
46 | I have.