Merge branch 'master' into gtkbuilder

Conflicts:
	src/interface.c
	src/vte.c
This commit is contained in:
Matthew Brush 2011-11-06 23:44:24 -08:00
commit 0a16ec7520
142 changed files with 19329 additions and 5234 deletions

4
.gitignore vendored
View File

@ -6,6 +6,8 @@
*.lo
*.so
*.dll
*.exe
deps.mak
.deps/
.libs/
Makefile
@ -35,11 +37,13 @@ Makefile.in
/geany.gladep.bak
/geany.pc
/geany.spec
/geany_private.res
/global.tags.old
/install-sh
/intltool
/intltool-*
/libtool
/localwin32.mk
/.lock-wscript
/ltmain.sh
/m4/

133
HACKING
View File

@ -144,18 +144,18 @@ And then simply apply it like so::
GTK versions & API documentation
--------------------------------
Geany requires GTK >= 2.12 and GLib >= 2.16. API symbols from newer
GTK/GLib versions should be avoided or made optional to keep the source
Geany requires GTK >= 2.16 and GLib >= 2.20. API symbols from newer
GTK/GLib versions should be avoided or made optional to keep the source
code building on older systems.
The official GTK 2.12 API documentation may not be available online
anymore, so we put it on http://www.geany.org/manual/gtk/. There
is also a tarball with all available files for download and use with
The official GTK 2.16 API documentation may not be available online
anymore, so we put it on http://www.geany.org/manual/gtk/. There
is also a tarball with all available files for download and use with
devhelp.
Using the 2.12 API documentation of the GTK libs (including GLib, GDK
and Pango) has the advantages that you don't get confused by any
newer API additions and you don't have to take care about whether
Using the 2.16 API documentation of the GTK libs (including GLib, GDK
and Pango) has the advantages that you don't get confused by any
newer API additions and you don't have to take care about whether
you can use them or not.
Coding
@ -164,14 +164,16 @@ Coding
them down into smaller static functions where possible. This makes code
much easier to read and maintain.
* Use GLib types and functions - gint not int, g_free() not free().
* Your code should build against GLib 2.16 and GTK 2.12. At least for the
moment, we want to keep the minimum requirement for GTK at 2.12 (of
* Your code should build against GLib 2.20 and GTK 2.16. At least for the
moment, we want to keep the minimum requirement for GTK at 2.16 (of
course, you can use the GTK_CHECK_VERSION macro to protect code using
later versions).
* Variables should be declared before statements. You can use
gcc's -Wdeclaration-after-statement to warn about this.
* Don't let variable names shadow outer variables - use gcc's -Wshadow
option.
* Do not use G_LIKELY or G_UNLIKELY (except in critical loops). These
add noise to the code with little real benefit.
Compiler options & warnings
^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -196,6 +198,9 @@ Style
* We use a tab width of 4 and indent completely with tabs not spaces.
Note the documentation files use (4) spaces instead, so you may want
to use the 'Detect from file' indent pref.
* Do not add whitespace at the end of lines, this adds to commit noise.
When editing with Geany set preference files->Strip trailing spaces
and tabs.
* Use the multiline comment ``/* */`` to comment small blocks of code,
functions descriptions or longer explanations of code, etc. C++ single
line comments will cause portability issues. The more comments are in
@ -221,19 +226,39 @@ Style
A few of the above can be done with the Git
``scripts/fix-alignment.pl``, but it is quite dumb and it's much better
to write it correctly in the first place.
``scripts/rstrip-whitespace.py`` just removes trailing whitespace.
.. below tabs should be used, but spaces are required for reST.
Example::
struct Bar;
typedef struct Foo /* struct names normally are the same as typedef names */
{
gint foo; /* names are somewhat aligned visually */
gint bar; /* fields don't share the same line */
SomeLongTypeName baz; /* alignment is not strict */
gchar *ptr; /* pointer symbol must go next to variable name, not type */
Bar public; /**< only plugin API fields have a doc-comment */
}
Foo;
gint some_func(void);
gint some_other_func(void);
/* optional function comment explains something important */
gint function_long_name(gchar arg1, <too many args to fit on this line>,
gchar argN)
{
/* variable declarations go before code in each scope */
/* variable declarations always go before code in each scope */
/* variable names should NOT be aligned at all */
gint foo, bar; /* variables can go on the same line */
gint baz; /* but often don't */
gchar *ptr; /* pointer symbol must go next to variable name, not type */
gchar *another; /* pointers should normally go on separate lines */
@ -242,7 +267,8 @@ Example::
* lines to explain */
if (foo)
{
gint dir = -1; /* -1 to search backwards */
/* variables only used in one scope should normally be declared there */
gint dir = -1;
bar = foo;
if ((bar & (guint)dir) != 7)
@ -254,6 +280,12 @@ Example::
}
/** Explains using doc-comments for plugin API functions.
* First line should be short and use the third person tense - 'explains',
* not 'explain'.
*
* @return Some number.
* @since 1.22. */
gint another_function(void)
{
...
@ -262,26 +294,40 @@ Example::
Committing
----------
Commit one thing at a time, do small commits. Commits should be
meaningful and not too big when possible; multiple small commits are
good if there is no good reason to group them.
When working on a new feature, create a new branch for it. When merging
it, use the --no-ff option to make sure a merge commit will be created
to better track what happened. However, if the feature only took one
commit you might merge it fast-forward since there is not history to
keep together.
* Commit one thing at a time, do small commits. Commits should be
meaningful and not too big when possible; multiple small commits are
good if there is no good reason to group them.
* Use meaningful name and email in the Author and Committer fields.
This helps knowing who did what and allows to contact the author if
there is a good reason to do so (unlikely, but can happen).
* When working on a new feature, create a new branch for it. When
merging it, use the --no-ff option to make sure a merge commit will
be created to better track what happened. However, if the feature
only took one commit you might merge it fast-forward since there is
not history to keep together.
Commit messages
^^^^^^^^^^^^^^^
Follow the standard Git formatting:
* First line is the commit's summary and should use less than about 80
characters, and is followed by an empty line. See it like the subject
of an email: keep it concise and as precise as you can, but not tool
long.
* No line should use more than about 80 characters (around 72 is best).
* The first line is the commit's summary and is followed by an empty
line. This summary should be one line and one line only, thus less
than 80 characters. This summary should not include any punctuation
unless really needed. See it as the subject of an email: keep it
concise and as precise as you can, but not tool long.
* Following lines are optional detailed commit information, with
paragraphs separated by blank lines.
paragraphs separated by blank lines. This part should be as long as
needed to describe the commit in depth, should use proper
punctuation and should include any useful information, like the
motivation for the patch and/or any valuable details the diff itself
don't provide or don't make clear. Make it as complete as you think
it makes sense, but don't include an information that is better
explained by the commit's diff.
It is OK to use ASCII formatting like bullet list using "*" or "-",
etc. if useful, but emphasis (bold, italic, underline) should be
avoided.
Example::
@ -440,7 +486,7 @@ For brace indentation, update lexer_has_braces() in editor.c;
indentation after ':' is done from on_new_line_added().
If the Scintilla lexer supports user type keyword highlighting (e.g.
SCLEX_CPP), update editor_lexer_get_type_keyword_idx() in editor.c.
SCLEX_CPP), update document_update_type_keywords() in document.c.
Adding a TagManager parser
^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -453,13 +499,13 @@ http://sf.net/projects/ctags - see the tracker.
(You can also try the Anjuta project's tagmanager codebase.)
.. note::
From Geany 1.22 GLib's GRegex engine is used instead of POSIX
regex, unlike CTags. It should be close enough to POSIX to work
From Geany 1.22 GLib's GRegex engine is used instead of POSIX
regex, unlike CTags. It should be close enough to POSIX to work
OK.
We no longer support regex parsers with the "b" regex flag
option set and Geany will print debug warnings if it's used.
CTags supports it but doesn't currently (2011) include any
parsers that use it. It should be easy to convert to extended
We no longer support regex parsers with the "b" regex flag
option set and Geany will print debug warnings if it's used.
CTags supports it but doesn't currently (2011) include any
parsers that use it. It should be easy to convert to extended
regex syntax anyway.
Method
@ -538,3 +584,24 @@ Example::
** INFO: Unloaded: ./plugins/.libs/demoplugin.so
(gdb) c
Continuing.
Building Plugins
^^^^^^^^^^^^^^^^
The geany-plugins autotools script automatically detects the
installed system Geany and builds the plugins against that.
To use plugins with a development version of Geany built with
a different prefix, the plugins will need to be compiled against
that version if the ABI has changed.
To do this you need to specify both --prefix and --with-geany-libdir
to the plugin configure. Normally the plugin prefix is the
same as the Geany prefix to keep plugins with the version of Geany
that they are compiled against, and with-geany-libdir is the Geany
prefix/lib.
Whilst it is possible for the plugin prefix to be different to
the prefix of the libdir (which is why there are two settings),
it is probably better to keep the version of Geany and its plugins
together.

6
NEWS
View File

@ -1,3 +1,9 @@
Geany 1.22 (unreleased)
Editor
* Update Scintilla to version 2.29.
Geany 0.21 (October 2, 2011)
General

2
README
View File

@ -28,7 +28,7 @@ The basic features of Geany are:
Requirements
------------
For compiling Geany yourself, you will need the GTK (>= 2.12.0)
For compiling Geany yourself, you will need the GTK (>= 2.16.0)
libraries and header files. You will also need its dependency libraries
and header files, such as Pango, Glib and ATK. All these files are
available at http://www.gtk.org.

2
THANKS
View File

@ -126,12 +126,14 @@ Chikahiro Masami <cmasa(dot)z321(at)gmail(dot)com> - ja
Park Jang-heon <dotkabi(at)gmail(dot)com> - ko
Baurzhan Muftakhidinov <baurthefirst(at)gmail(dot)com> - kk
Laurent Hoeltgen <hoeltgman(at)gmail(dot)com> - lb
tsetsee <tsetsee(dot)yugi(at)gmail(dot)com> - mn
Kurt De Bree <kdebree(at)telenet(dot)be> - nl
Peter Scholtens <<peter(dot)scholtens(at)xs4all(dot)nl> - nl
Ayke van Laethem <aykevanlaethem(at)gmail(dot)com> - nl
Jacek Wolszczak <shutdownrunner(at)o2(dot)pl> - pl_PL
Jarosław Foksa <jfoksa(at)gmail(dot)com> - pl_PL
Krzysztof Troska <elleander86(at)gmail(dot)com> - pl_PL
Wojciech Świderski <woj.swiderski@gmail.com> - pl_PL
Alexandre Moreira <alexandream(at)gmail(dot)com> - pt_BR
Adrovane Marques Kade <adrovane(at)gmail(dot)com> - pt_BR
Rafael Peregrino da Silva <rperegrino(at)linuxnewmedia(dot)com(dot)br - pt_BR

View File

@ -57,7 +57,7 @@ GEANY_CHECK_REVISION([dnl force debug mode for a SVN working copy
# GTK/GLib/GIO checks
gtk_modules="gtk+-2.0 >= 2.12 glib-2.0 >= 2.16 gio-2.0 >= 2.16"
gtk_modules="gtk+-2.0 >= 2.16 glib-2.0 >= 2.20 gio-2.0 >= 2.20"
PKG_CHECK_MODULES([GTK], [$gtk_modules])
AC_SUBST([GTK_CFLAGS])
AC_SUBST([GTK_LIBS])

View File

@ -66,7 +66,7 @@ string_3=default
string_4=default
string_eol=0x000000;0xe0c0e0
character=string_1
backtick=string_2
backticks=string_2
here_doc=string_2
scalar=string_2

View File

@ -10,8 +10,8 @@ character=string_1
charactereol=string_eol
string=string_1
stringeol=string_eol
label=preprocessor
commentline=comment
label=label
commentline=comment_line
illegal=error
[keywords]

View File

@ -2,7 +2,9 @@
[styling]
# Edit these in the colorscheme .conf file instead
default=default
comment=comment
comment=comment_line
commentblock=comment
commentdirective=comment
number=number_1
string=string_1
operator=operator
@ -12,7 +14,6 @@ mathinstruction=keyword_2
register=type
directive=preprocessor
directiveoperand=keyword_3
commentblock=comment
character=string_1
stringeol=string_eol
extinstruction=keyword_4

View File

@ -3,7 +3,7 @@
# Edit these in the colorscheme .conf file instead
default=default
comment=comment
commentline=comment
commentline=comment_line
commentdoc=comment_doc
number=number_1
word=keyword_1
@ -17,7 +17,7 @@ identifier=identifier_1
stringeol=string_eol
verbatim=string_2
regex=regex
commentlinedoc=comment_doc
commentlinedoc=comment_line_doc
commentdockeyword=comment_doc_keyword
commentdockeyworderror=comment_doc_keyword_error
globalclass=class

View File

@ -9,12 +9,14 @@ comment3=comment
number=number_1
keyword=keyword_1
keyword2=keyword_2
keyword3=keyword_3
string=string_1
char=string_1
char=character
operator=operator
identifier=identifier_1
tagname=preprocessor
linenum=number_2
white=default
[keywords]
# all items must be in one line

View File

@ -3,7 +3,7 @@
# Edit these in the colorscheme .conf file instead
default=default
comment=comment
commentline=comment
commentline=comment_line
commentdoc=comment_doc
number=number_1
word=keyword_1

View File

@ -151,7 +151,7 @@ string_1=string
string_2=string_1
string_eol=0x000000;0xe0c0e0;false;false
character=string_1
backtick=string_2
backticks=string_2
here_doc=string_2
scalar=string_2

View File

@ -11,7 +11,7 @@ unknown_identifier=class
operator=operator
identifier=keyword_1
doublestring=string_1
singlestring=string_1
singlestring=string_2
attribute=attribute
value=value
id=number
@ -23,7 +23,7 @@ pseudoelement=element
extended_identifier=keyword_4
extended_pseudoclass=class
extended_pseudoelement=element
media=string_2
media=string_3
[keywords]
# CSS 1 properties

View File

@ -3,7 +3,7 @@
# Edit these in the colorscheme .conf file instead
default=default
comment=comment
commentline=comment
commentline=comment_line
commentdoc=comment_doc
commentdocnested=comment_doc
number=number_1
@ -13,10 +13,10 @@ word3=keyword_3
typedef=type
string=string_1
stringeol=string_eol
character=string_1
character=character
operator=operator
identifier=identifier_1
commentlinedoc=comment_doc
commentlinedoc=comment_line_doc
commentdockeyword=comment_doc_keyword
commentdockeyworderror=comment_doc_keyword_error

View File

@ -16,7 +16,7 @@ word3=keyword_3
word4=keyword_4
constant=identifier_2
asm=type
label=identifier_3
label=label
error=error
hexnumber=number_1
binnumber=number_1

View File

@ -2,7 +2,7 @@
[styling]
# Edit these in the colorscheme .conf file instead
default=default
commentline=comment
commentline=comment_line
commentblock=comment
commentblock2=comment
commentblock3=comment
@ -10,7 +10,7 @@ number=number_1
keyword=keyword_1
import=preprocessor
string=string_1
character=string_2
character=character
class=class
operator=operator
identifier=identifier_1

View File

@ -3,7 +3,7 @@
[keywords]
# all items must be in one line
primary=break case catch const continue default delete do each else false finally for function get if in Infinity instanceof let NaN new null return set switch this throw true try typeof undefined var void while with yield
primary=break case catch const continue default delete do each else false finally for function get if in Infinity instanceof let NaN new null return set switch this throw true try typeof undefined var void while with yield prototype
secondary=Array Boolean Date Function Math Number Object String RegExp EvalError Error RangeError ReferenceError SyntaxError TypeError URIError prototype decodeURI decodeURIComponent encodeURI encodeURIComponent eval isFinite isNaN parseFloat parseInt
[settings]

View File

@ -6,6 +6,15 @@ command=keyword_1
tag=tag
math=number_1
comment=comment
# mappings below may need checking
tag2=tag
math2=number_1
comment2=comment
verbatim=default
shortcmd=keyword_1
special=keyword_2
cmdopt=keyword_1
error=error
[keywords]
# all items must be in one line
@ -48,8 +57,8 @@ context_action_cmd=
compiler=latex --file-line-error-style "%f"
# it is called linker, but here it is an alternative compiler command
linker=pdflatex --file-line-error-style "%f"
run_cmd=xdvi "%e.dvi"
run_cmd2=xpdf "%e.pdf"
run_cmd=evince "%e.dvi"
run_cmd2=evince "%e.pdf"
[build-menu]
FT_00_LB=LaTeX -> _DVI
@ -59,8 +68,8 @@ FT_01_LB=LaTeX -> _PDF
FT_01_CM=pdflatex --file-line-error-style "%f"
FT_01_BD=false
EX_00_LB=V_iew PDF File
EX_00_CM=xpdf "%e.pdf"
EX_00_CM=evince "%e.pdf"
EX_00_BD=false
EX_01_LB=_View DVI File
EX_01_CM=xdvi "%e.dvi"
EX_01_CM=evince "%e.dvi"
EX_01_BD=false

View File

@ -2,20 +2,17 @@
[styling]
# Edit these in the colorscheme .conf file instead
default=default
comment=comment
comment=comment_line
multicomment=comment
number=number_1
keyword=keyword_1
special_keyword=type
keywordkw=keyword_2
symbol=keyword_2
string=string_1
stringeol=string_eol
identifier=identifier_1
operator=operator
special=function
character=character
macro=preprocessor
macrodispatch=number_2
[keywords]
# all items must be in one line

View File

@ -21,6 +21,7 @@ word5=keyword_1
word6=keyword_2
word7=keyword_3
word8=keyword_4
label=label
[keywords]
# all items must be in one line

View File

@ -2,7 +2,7 @@
[styling]
# Edit these in the colorscheme .conf file instead
default=default
comment=comment
comment=comment_line
stringdq=string_1
stringlq=string_2
stringrq=string_2

View File

@ -4,8 +4,8 @@
default=default
identifier=identifier_1
comment=comment
comment2=comment
commentline=comment
comment2=comment_doc
commentline=comment_line
preprocessor=preprocessor
preprocessor2=preprocessor
number=number_1

View File

@ -3,7 +3,7 @@
# Edit these in the colorscheme .conf file instead
default=default
error=error
commentline=comment
commentline=comment_line
number=number_1
word=keyword_1
string=string_1
@ -31,13 +31,25 @@ string_qx=string_2
string_qr=string_2
string_qw=string_2
variable_indexer=default
# *_var mappings may need checking
string_var=identifier_1
regex_var=identifier_2
regsubst_var=identifier_2
backticks_var=identifier_2
here_qq_var=identifier_2
here_qx_var=identifier_2
string_qq_var=identifier_2
string_qx_var=identifier_2
string_qr_var=identifier_2
# translation: tr{}{} y{}{}
xlat=string_2
# not used
punctuation=default
# obsolete: replaced by qq, qx, qr, qw
longquote=perl_here_qq
sub_prototype=perl_here_qx
format_ident=perl_string_qr
format=perl_string_qw
longquote=here_doc
sub_prototype=here_doc
format_ident=string_2
format=string_2
[keywords]
primary=NULL __FILE__ __LINE__ __PACKAGE__ __DATA__ __END__ AUTOLOAD BEGIN CORE DESTROY END EQ GE GT INIT LE LT NE CHECK abs accept alarm and atan2 bind binmode bless caller chdir chmod chomp chop chown chr chroot close closedir cmp connect continue cos crypt dbmclose dbmopen defined delete die do dump each else elsif endgrent endhostent endnetent endprotoent endpwent endservent eof eq eval exec exists exit exp fcntl fileno flock for foreach fork format formline ge getc getgrent getgrgid getgrnam gethostbyaddr gethostbyname gethostent getlogin getnetbyaddr getnetbyname getnetent getpeername getpgrp getppid getpriority getprotobyname getprotobynumber getprotoent getpwent getpwnam getpwuid getservbyname getservbyport getservent getsockname getsockopt glob gmtime goto grep gt hex if index int ioctl join keys kill last lc lcfirst le length link listen local localtime lock log lstat lt m map mkdir msgctl msgget msgrcv msgsnd my ne next no not oct open opendir or ord our pack package pipe pop pos print printf prototype push q qq qr quotemeta qu qw qx rand read readdir readline readlink readpipe recv redo ref rename require reset return reverse rewinddir rindex rmdir s scalar seek seekdir select semctl semget semop send setgrent sethostent setnetent setpgrp setpriority setprotoent setpwent setservent setsockopt shift shmctl shmget shmread shmwrite shutdown sin sleep socket socketpair sort splice split sprintf sqrt srand stat study sub substr symlink syscall sysopen sysread sysseek system syswrite tell telldir tie tied time times tr truncate uc ucfirst umask undef unless unlink unpack unshift untie until use utime values vec wait waitpid wantarray warn while write x xor y

View File

@ -2,7 +2,7 @@
[styling]
# Edit these in the colorscheme .conf file instead
default=default
commentline=comment
commentline=comment_line
number=number_1
string=string_1
character=character

View File

@ -2,7 +2,7 @@
[styling]
# Edit these in the colorscheme .conf file instead
default=default
commentline=comment
commentline=comment_line
number=number_1
string=string_1
character=character

View File

@ -2,14 +2,14 @@
[styling]
# Edit these in the colorscheme .conf file instead
default=default
commentline=comment
commentline=comment_line
number=number_1
word=keyword_1
string=string_1
character=string_1
character=character
operator=operator
identifier=identifier_1
backticks=backtick
backticks=backticks
param=parameter
scalar=scalar
error=error

View File

@ -4,7 +4,10 @@
default=default
comment=comment
commentline=comment_line
commentlinedoc=comment_line_doc
commentdoc=comment_doc
commentdockeyword=comment_doc_keyword
commentdockeyworderror=comment_doc_keyword_error
number=number_1
word=keyword_1
word2=keyword_2
@ -14,7 +17,7 @@ operator=operator
identifier=identifier_1
sqlplus=default
sqlplus_prompt=default
sqlplus_comment=default
sqlplus_comment=comment
quotedidentifier=identifier_2
[keywords]

View File

@ -4,6 +4,8 @@
default=default
comment=comment
commentline=comment_line
commentbox=comment
blockcomment=comment
number=number_1
operator=operator
identifier=identifier_1

View File

@ -39,22 +39,22 @@ php_default=default
php_simplestring=string_1
php_hstring=string_1
php_number=number_1
php_word=number_2
php_variable=identifier_4
php_word=keyword_1
php_variable=preprocessor
php_comment=comment
php_commentline=comment
php_commentline=comment_line
php_operator=operator
php_hstring_variable=string_2
php_complex_variable=identifier_2
php_complex_variable=preprocessor
jscript_start=tag
jscript_default=default
jscript_comment=comment
jscript_commentline=comment
jscript_commentline=comment_line
jscript_commentdoc=comment_doc
jscript_number=number_1
jscript_word=number_2
jscript_keyword=keyword_1
jscript_word=keyword_1
jscript_keyword=keyword_2
jscript_doublestring=string_1
jscript_singlestring=string_1

View File

@ -2,11 +2,13 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.8.1: http://docutils.sourceforge.net/" />
<meta name="generator" content="Docutils 0.9: http://docutils.sourceforge.net/" />
<title>Geany</title>
<meta name="authors" content="Enrico Tröger Nick Treleaven Frank Lanitz Colomban Wendling" />
<meta name="date" content="2011-10-01" />
<meta name="date" content="2011-10-02" />
<style type="text/css">
/*
@ -125,11 +127,14 @@ Stylesheet for Geany's documentation based on a version of John Gabriele.
}
</style>
</head>
<body>
<div class="document" id="geany">
<h1 class="title">Geany</h1>
<h2 class="subtitle" id="a-fast-light-gtk-ide">A fast, light, GTK+ IDE</h2>
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
@ -140,11 +145,12 @@ Stylesheet for Geany's documentation based on a version of John Gabriele.
<br />Frank Lanitz
<br />Colomban Wendling</td></tr>
<tr><th class="docinfo-name">Date:</th>
<td>2011-10-01</td></tr>
<td>2011-10-02</td></tr>
<tr><th class="docinfo-name">Version:</th>
<td>0.21</td></tr>
<td>1.22</td></tr>
</tbody>
</table>
<p>Copyright © 2005-2011</p>
<p>This document is distributed under the terms of the GNU General Public
License as published by the Free Software Foundation; either version 2
@ -507,13 +513,14 @@ of this program, and also in the chapter <a class="reference internal" href="#gn
<li><a class="reference internal" href="#compile-time-options" id="id231">Compile-time options</a><ul>
<li><a class="reference internal" href="#src-geany-h" id="id232">src/geany.h</a></li>
<li><a class="reference internal" href="#project-h" id="id233">project.h</a></li>
<li><a class="reference internal" href="#editor-h" id="id234">editor.h</a></li>
<li><a class="reference internal" href="#keyfile-c" id="id235">keyfile.c</a></li>
<li><a class="reference internal" href="#build-c" id="id236">build.c</a></li>
<li><a class="reference internal" href="#filetypes-c" id="id234">filetypes.c</a></li>
<li><a class="reference internal" href="#editor-h" id="id235">editor.h</a></li>
<li><a class="reference internal" href="#keyfile-c" id="id236">keyfile.c</a></li>
<li><a class="reference internal" href="#build-c" id="id237">build.c</a></li>
</ul>
</li>
<li><a class="reference internal" href="#gnu-general-public-license" id="id237">GNU General Public License</a></li>
<li><a class="reference internal" href="#license-for-scintilla-and-scite" id="id238">License for Scintilla and SciTE</a></li>
<li><a class="reference internal" href="#gnu-general-public-license" id="id238">GNU General Public License</a></li>
<li><a class="reference internal" href="#license-for-scintilla-and-scite" id="id239">License for Scintilla and SciTE</a></li>
</ul>
</div>
<div class="section" id="introduction">
@ -570,7 +577,7 @@ The latest version can always be found at <a class="reference external" href="ht
<h1><a class="toc-backref" href="#id12">Installation</a></h1>
<div class="section" id="requirements">
<h2><a class="toc-backref" href="#id13">Requirements</a></h2>
<p>You will need the GTK (&gt;= 2.12.0) libraries and their dependencies
<p>You will need the GTK (&gt;= 2.16.0) libraries and their dependencies
(Pango, GLib and ATK). Your distro should provide packages for these,
usually installed by default. For Windows, you can download an installer
from the website which bundles these libraries.</p>
@ -583,7 +590,7 @@ incomplete list see <a class="reference external" href="http://www.geany.org/Dow
<div class="section" id="source-compilation">
<h2><a class="toc-backref" href="#id15">Source compilation</a></h2>
<p>Compiling Geany is quite easy.
To do so, you need the GTK (&gt;= 2.12.0) libraries and header files.
To do so, you need the GTK (&gt;= 2.16.0) libraries and header files.
You also need the Pango, GLib and ATK libraries and header files.
All these files are available at <a class="reference external" href="http://www.gtk.org">http://www.gtk.org</a>, but very often
your distro will provide development packages to save the trouble of
@ -2054,6 +2061,15 @@ of header files. When Geany is next started, your custom tags file
will be loaded instead of the default c99.tags. You should keep a
copy of the generated tags file because it will get overwritten when
upgrading Geany.</p>
<p><em>Generating tag files on Windows:</em></p>
<p>This works basically the same as on other platforms but you need to make
sure you have grep installed and Geany can find it, i.e. it must be
in the PATH environment variable. To test this, open a console window
and type <tt class="docutils literal">grep</tt> and see whether it is executed.
If it is, then you can create a tags file like the following:</p>
<pre class="literal-block">
&quot;c:\program files\geany\bin\geany&quot; -g c:\mytags.php.tags c:\code\somefile.php
</pre>
</div>
</div>
<div class="section" id="c-ignore-tags">
@ -2866,10 +2882,10 @@ internal default, which is currently:</p>
<p>Note that <tt class="docutils literal">\t</tt> = tab.</p>
<table border="1" class="docutils">
<colgroup>
<col width="34%" />
<col width="46%" />
<col width="9%" />
<col width="12%" />
<col width="33%" />
<col width="45%" />
<col width="10%" />
<col width="11%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">Key</th>
@ -2943,6 +2959,17 @@ saving. Backup is named <cite>filename~</cite>.</td>
<td>false</td>
<td>immediately</td>
</tr>
<tr><td><strong>Filetype related</strong></td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr><td>extract_filetype_regex</td>
<td>Regex to extract filetype name from file
via capture group one.</td>
<td>See below.</td>
<td>immediately</td>
</tr>
<tr><td><strong>Search related</strong></td>
<td>&nbsp;</td>
<td>&nbsp;</td>
@ -2978,6 +3005,7 @@ execute section of the Build menu.</td>
</tr>
</tbody>
</table>
<p>The extract_filetype_regex has the default value GEANY_DEFAULT_FILETYPE_REGEX.</p>
</div>
<div class="section" id="terminal-vte-preferences">
<h3><a class="toc-backref" href="#id126">Terminal (VTE) preferences</a></h3>
@ -5198,7 +5226,7 @@ is enabled (see View menu).</p>
</dd>
<dt>marker_search</dt>
<dd><p class="first">The style for a marked search results (when using &quot;Mark&quot; in Search dialogs).
The second argument sets the background colour for the drawn rectangle.</p>
The second argument sets the background color for the drawn rectangle.</p>
<p>Only the second argument is interpreted.</p>
<p class="last"><em>Example:</em> <tt class="docutils literal">marker_search=0x000000;0xb8f4b8;false;false</tt></p>
</dd>
@ -5558,7 +5586,7 @@ bsd, gpl, snippets.</td>
</tr>
<tr><td>geanyversion</td>
<td>The actual Geany version, e.g.
&quot;Geany 0.21&quot;.</td>
&quot;Geany 1.22&quot;.</td>
<td>file templates, file header,
function description, ChangeLog entry,
bsd, gpl, snippets.</td>
@ -5890,7 +5918,7 @@ editing the file, to build the HTML document to see how your changes
look, run &quot;<tt class="docutils literal">make doc</tt>&quot; in the subdirectory <tt class="docutils literal">doc</tt> of Geany's source
directory. This regenerates the <tt class="docutils literal">geany.html</tt> file. To generate a PDF
file, use the command &quot;<tt class="docutils literal">make pdf</tt>&quot; which should generate a file called
geany-0.21.pdf.</p>
geany-1.22.pdf.</p>
<p>After you are happy with your changes, create a patch:</p>
<pre class="literal-block">
% svn diff geany.txt &gt; foo.patch
@ -6131,8 +6159,31 @@ open dialog.</td>
</tbody>
</table>
</div>
<div class="section" id="filetypes-c">
<h2><a class="toc-backref" href="#id234">filetypes.c</a></h2>
<table border="1" class="docutils">
<colgroup>
<col width="33%" />
<col width="48%" />
<col width="20%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">Option</th>
<th class="head">Description</th>
<th class="head">Default</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>GEANY_FILETYPE_SEARCH_LINES</td>
<td>The number of lines to search for the
filetype with the extract filetype regex.</td>
<td>2</td>
</tr>
</tbody>
</table>
</div>
<div class="section" id="editor-h">
<h2><a class="toc-backref" href="#id234">editor.h</a></h2>
<h2><a class="toc-backref" href="#id235">editor.h</a></h2>
<table border="1" class="docutils">
<colgroup>
<col width="33%" />
@ -6158,7 +6209,7 @@ underscore.</td>
</table>
</div>
<div class="section" id="keyfile-c">
<h2><a class="toc-backref" href="#id235">keyfile.c</a></h2>
<h2><a class="toc-backref" href="#id236">keyfile.c</a></h2>
<p>These are default settings that can be overridden in the <a class="reference internal" href="#preferences">Preferences</a> dialog.</p>
<table border="1" class="docutils">
<colgroup>
@ -6235,11 +6286,17 @@ comment.</td>
Geany provide.</td>
<td>30</td>
</tr>
<tr><td>GEANY_DEFAULT_FILETYPE_REGEX</td>
<td>The default regex to extract filetypes from
files.</td>
<td>See below.</td>
</tr>
</tbody>
</table>
<p>The GEANY_DEFAULT_FILETYPE_REGEX default value is -\*-\s*([^\s]+)\s*-\*- which finds Emacs filetypes.</p>
</div>
<div class="section" id="build-c">
<h2><a class="toc-backref" href="#id236">build.c</a></h2>
<h2><a class="toc-backref" href="#id237">build.c</a></h2>
<table border="1" class="docutils">
<colgroup>
<col width="33%" />
@ -6284,7 +6341,7 @@ overriding the compile setting.</td>
</div>
</div>
<div class="section" id="gnu-general-public-license">
<h1><a class="toc-backref" href="#id237">GNU General Public License</a></h1>
<h1><a class="toc-backref" href="#id238">GNU General Public License</a></h1>
<pre class="literal-block">
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
@ -6629,7 +6686,7 @@ Public License instead of this License.
</pre>
</div>
<div class="section" id="license-for-scintilla-and-scite">
<h1><a class="toc-backref" href="#id238">License for Scintilla and SciTE</a></h1>
<h1><a class="toc-backref" href="#id239">License for Scintilla and SciTE</a></h1>
<p>Copyright 1998-2003 by Neil Hodgson &lt;neilh(at)scintilla(dot)org&gt;</p>
<p>All Rights Reserved</p>
<p>Permission to use, copy, modify, and distribute this software and
@ -6645,13 +6702,15 @@ OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
USE OR PERFORMANCE OF THIS SOFTWARE.</p>
</div>
</div>
<div class="footer">
<hr class="footer" />
<a class="reference external" href="geany.txt">View document source</a>.
Generated on: 2011-10-02 13:04 UTC.
Generated on: 2011-11-03 18:14 UTC.
Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
</div>
</body>
</html>

View File

@ -101,7 +101,7 @@ Installation
Requirements
------------
You will need the GTK (>= 2.12.0) libraries and their dependencies
You will need the GTK (>= 2.16.0) libraries and their dependencies
(Pango, GLib and ATK). Your distro should provide packages for these,
usually installed by default. For Windows, you can download an installer
from the website which bundles these libraries.
@ -118,7 +118,7 @@ Source compilation
------------------
Compiling Geany is quite easy.
To do so, you need the GTK (>= 2.12.0) libraries and header files.
To do so, you need the GTK (>= 2.16.0) libraries and header files.
You also need the Pango, GLib and ATK libraries and header files.
All these files are available at http://www.gtk.org, but very often
your distro will provide development packages to save the trouble of
@ -1662,6 +1662,17 @@ will be loaded instead of the default c99.tags. You should keep a
copy of the generated tags file because it will get overwritten when
upgrading Geany.
*Generating tag files on Windows:*
This works basically the same as on other platforms but you need to make
sure you have grep installed and Geany can find it, i.e. it must be
in the PATH environment variable. To test this, open a console window
and type ``grep`` and see whether it is executed.
If it is, then you can create a tags file like the following::
"c:\program files\geany\bin\geany" -g c:\mytags.php.tags c:\code\somefile.php
C ignore.tags
^^^^^^^^^^^^^
@ -2485,14 +2496,14 @@ internal default, which is currently:
Note that ``\t`` = tab.
================================ =========================================== ======== ===========
Key Description Default Applies
================================ =========================================== ======== ===========
================================ =========================================== ========== ===========
Key Description Default Applies
================================ =========================================== ========== ===========
**VTE related**
emulation Terminal emulation mode. Only change this xterm immediately
emulation Terminal emulation mode. Only change this xterm immediately
if you have VTE termcap files other than
``vte/termcap/xterm``.
send_selection_unsafe By default, Geany strips any trailing false immediately
send_selection_unsafe By default, Geany strips any trailing false immediately
newline characters from the current
selection before sending it to the terminal
to not execute arbitrary code. This is
@ -2501,7 +2512,7 @@ send_selection_unsafe By default, Geany strips any trailing f
it to be executed directly, set this option
to true.
**File related**
use_atomic_file_saving Defines the mode how Geany saves files to false immediately
use_atomic_file_saving Defines the mode how Geany saves files to false immediately
disk. If disabled, Geany directly writes
the content of the document to disk. This
might cause loss of data when there is
@ -2518,23 +2529,27 @@ use_atomic_file_saving Defines the mode how Geany saves files to f
break things seriously.
The better approach would be to ensure your
disk won't run out of free space.
use_gio_unsafe_file_saving Whether to use GIO as the unsafe file true immediately
use_gio_unsafe_file_saving Whether to use GIO as the unsafe file true immediately
saving backend. It is better on most
situations but is known not to work
correctly on some complex setups.
gio_unsafe_save_backup Make a backup when using GIO unsafe file false immediately
gio_unsafe_save_backup Make a backup when using GIO unsafe file false immediately
saving. Backup is named `filename~`.
**Filetype related**
extract_filetype_regex Regex to extract filetype name from file See below. immediately
via capture group one.
**Search related**
find_selection_type See `Find selection`_. 0 immediately
find_selection_type See `Find selection`_. 0 immediately
**Build Menu related**
number_ft_menu_items The maximum number of menu items in the 2 on restart
number_ft_menu_items The maximum number of menu items in the 2 on restart
filetype section of the Build menu.
number_non_ft_menu_items The maximum number of menu items in the 3 on restart
number_non_ft_menu_items The maximum number of menu items in the 3 on restart
independent section of the Build menu.
number_exec_menu_items The maximum number of menu items in the 2 on restart
number_exec_menu_items The maximum number of menu items in the 2 on restart
execute section of the Build menu.
================================ =========================================== ======== ===========
================================ =========================================== ========== ===========
The extract_filetype_regex has the default value GEANY_DEFAULT_FILETYPE_REGEX.
Terminal (VTE) preferences
^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -4353,7 +4368,7 @@ marker_line
marker_search
The style for a marked search results (when using "Mark" in Search dialogs).
The second argument sets the background colour for the drawn rectangle.
The second argument sets the background color for the drawn rectangle.
Only the second argument is interpreted.
@ -5100,6 +5115,16 @@ GEANY_PROJECT_EXT The default filename extension for Geany ge
open dialog.
============================== ============================================ ==================
filetypes.c
-----------
============================== ============================================ ==================
Option Description Default
============================== ============================================ ==================
GEANY_FILETYPE_SEARCH_LINES The number of lines to search for the 2
filetype with the extract filetype regex.
============================== ============================================ ==================
editor.h
--------
@ -5142,8 +5167,12 @@ GEANY_TOGGLE_MARK A string which is used to mark a toggled "~
comment.
GEANY_MAX_AUTOCOMPLETE_WORDS How many autocompletion suggestions should 30
Geany provide.
GEANY_DEFAULT_FILETYPE_REGEX The default regex to extract filetypes from See below.
files.
============================== ============================================ ==================
The GEANY_DEFAULT_FILETYPE_REGEX default value is -\\*-\\s*([^\\s]+)\\s*-\\*- which finds Emacs filetypes.
build.c
-------

View File

@ -7,6 +7,7 @@
RST2HTML=python rst2html.py
DOXYGEN=doxygen
CP = copy
RM = del
-include ../localwin32.mk
@ -16,6 +17,10 @@ doc: geany.txt
hacking-doc: ../HACKING
$(RST2HTML) -stg --stylesheet=geany.css $^ hacking.html
# FIXME: we should also replace anything like @VERSION@
Doxyfile: Doxyfile.in
$(CP) $< $@
api-doc: Doxyfile
$(DOXYGEN)

View File

@ -32,7 +32,8 @@
* @link plugindata.h @endlink.
*/
/** Use the PLUGIN_VERSION_CHECK() macro instead. Required by Geany. */
/** Use the PLUGIN_VERSION_CHECK() macro instead. Required by Geany.
* @return . */
gint plugin_version_check(gint);
/** Use the PLUGIN_SET_INFO() macro to define it. Required by Geany.

View File

@ -8,7 +8,7 @@ localedir=@localedir@
Name: Geany
Description: A fast and lightweight IDE using GTK2
Requires: gtk+-2.0 >= 2.12.0
Requires: gtk+-2.0 >= 2.16.0
Version: @VERSION@
Libs: -L${libdir}
Cflags: -DGTK -I${includedir}/geany -I${includedir}/geany/tagmanager -I${includedir}/geany/scintilla

View File

@ -132,36 +132,30 @@ static const gchar templates_gtk_class_header[] = "{fileheader}\n\n\
{base_include}\n\
G_BEGIN_DECLS\n\
\n\n\
#define {namespace_up}TYPE_{class_name_up} ({namespace_low}{class_name_low}_get_type())\n\
#define {namespace_up}{class_name_up}(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),\\\n\
{namespace_up}TYPE_{class_name_up}, {namespace}{class_name}))\n\
#define {namespace_up}{class_name_up}_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),\\\n\
{namespace_up}TYPE_{class_name_up}, {namespace}{class_name}Class))\n\
#define {namespace_up}IS_{class_name_up}(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),\\\n\
{namespace_up}TYPE_{class_name_up}))\n\
#define {namespace_up}IS_{class_name_up}_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),\\\n\
{namespace_up}TYPE_{class_name_up}))\n\
#define {namespace_up}{class_name_up}_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),\\\n\
{namespace_up}TYPE_{class_name_up}, {namespace}{class_name}Class))\n\
#define {namespace_up}TYPE_{class_name_up} ({namespace_low}{class_name_low}_get_type ())\n\
#define {namespace_up}{class_name_up}(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), {namespace_up}TYPE_{class_name_up}, {namespace}{class_name}))\n\
#define {namespace_up}{class_name_up}_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), {namespace_up}TYPE_{class_name_up}, {namespace}{class_name}Class))\n\
#define {namespace_up}IS_{class_name_up}(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), {namespace_up}TYPE_{class_name_up}))\n\
#define {namespace_up}IS_{class_name_up}_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), {namespace_up}TYPE_{class_name_up}))\n\
#define {namespace_up}{class_name_up}_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), {namespace_up}TYPE_{class_name_up}, {namespace}{class_name}Class))\n\
\n\
typedef struct _{namespace}{class_name} {namespace}{class_name};\n\
typedef struct _{namespace}{class_name}Class {namespace}{class_name}Class;\n\
typedef struct _{namespace}{class_name}Private {namespace}{class_name}Private;\n\
typedef struct _{namespace}{class_name} {namespace}{class_name};\n\
typedef struct _{namespace}{class_name}Class {namespace}{class_name}Class;\n\
typedef struct _{namespace}{class_name}Private {namespace}{class_name}Private;\n\
\n\
struct _{namespace}{class_name}\n\
{\n\
{base_name} parent;\n\
/* add your public declarations here */\n\
\n\
{namespace}{class_name}Private *priv;\n\
{base_name} parent;\n\
/* add your public declarations here */\n\
{namespace}{class_name}Private *priv;\n\
};\n\
\n\
struct _{namespace}{class_name}Class\n\
{\n\
{base_name}Class parent_class;\n\
{base_name}Class parent_class;\n\
};\n\
\n\n\
GType {namespace_low}{class_name_low}_get_type (void);\n\
GType {namespace_low}{class_name_low}_get_type (void);\n\n\
{constructor_decl}\
\n\n\
G_END_DECLS\n\
@ -174,26 +168,27 @@ static const gchar templates_gtk_class_source[] = "{fileheader}\n\
\n\
struct _{namespace}{class_name}Private\n\
{\n\
/* add your private declarations here */\n\
/* add your private declarations here */\n\
gpointer delete_me;\n\
};\n\
\n\
{destructor_decl}\
\n\
G_DEFINE_TYPE({namespace}{class_name}, {namespace_low}{class_name_low}, {base_gtype})\n\
G_DEFINE_TYPE ({namespace}{class_name}, {namespace_low}{class_name_low}, {base_gtype})\n\
\n\n\
static void {namespace_low}{class_name_low}_class_init({namespace}{class_name}Class *klass)\n\
static void\n\
{namespace_low}{class_name_low}_class_init ({namespace}{class_name}Class *klass)\n\
{\n\
{gtk_destructor_registration}\n\
g_type_class_add_private((gpointer)klass, sizeof({namespace}{class_name}Private));\n\
{gtk_destructor_registration}\n\
g_type_class_add_private ((gpointer)klass, sizeof ({namespace}{class_name}Private));\n\
}\n\
\n\
{destructor_impl}\n\
\n\
static void {namespace_low}{class_name_low}_init({namespace}{class_name} *self)\n\
static void\n\
{namespace_low}{class_name_low}_init ({namespace}{class_name} *self)\n\
{\n\
self->priv = G_TYPE_INSTANCE_GET_PRIVATE(self,\n\
{namespace_up}TYPE_{class_name_up}, {namespace}{class_name}Private);\n\
\n\
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, {namespace_up}TYPE_{class_name_up}, {namespace}{class_name}Private);\n\
}\n\
\n\
{constructor_impl}\n\
@ -876,14 +871,15 @@ static gboolean create_class(CreateClassDialog *cc_dlg)
class_info->source = g_strdup(gtk_entry_get_text(GTK_ENTRY(cc_dlg->source_entry)));
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cc_dlg->create_constructor_box)))
{
class_info->constructor_decl = g_strdup_printf("%s*\t%s%s_new\t\t\t(void);\n",
class_info->constructor_decl = g_strdup_printf("%s *%s%s_new (void);\n",
gtk_entry_get_text(GTK_ENTRY(cc_dlg->gtk_constructor_type_entry)),
class_info->namespace_low, class_info->class_name_low);
class_info->constructor_impl = g_strdup_printf("\n"
"%s *%s%s_new(void)\n"
"%s *\n"
"%s%s_new (void)\n"
"{\n"
"\treturn g_object_new(%sTYPE_%s, NULL);\n"
"}\n",
" return g_object_new (%sTYPE_%s, NULL);\n"
"}",
gtk_entry_get_text(GTK_ENTRY(cc_dlg->gtk_constructor_type_entry)),
class_info->namespace_low, class_info->class_name_low,
class_info->namespace_up, class_info->class_name_up);
@ -897,20 +893,20 @@ static gboolean create_class(CreateClassDialog *cc_dlg)
{
class_info->gtk_destructor_registration =
g_strdup_printf("GObjectClass *g_object_class;\n\n"
"\tg_object_class = G_OBJECT_CLASS(klass);\n\n"
"\tg_object_class->finalize = %s%s_finalize;\n",
" g_object_class = G_OBJECT_CLASS (klass);\n\n"
" g_object_class->finalize = %s%s_finalize;\n",
class_info->namespace_low, class_info->class_name_low);
class_info->destructor_decl =
g_strdup_printf("static void %s%s_finalize\t\t\t(GObject *object);\n",
g_strdup_printf("static void %s%s_finalize (GObject *object);\n",
class_info->namespace_low, class_info->class_name_low);
class_info->destructor_impl = g_strdup_printf("\n"
"static void %s%s_finalize(GObject *object)\n"
"static void\n"
"%s%s_finalize (GObject *object)\n"
"{\n"
"\t%s%s *self;\n\n"
"\tg_return_if_fail(object != NULL);\n"
"\tg_return_if_fail(%sIS_%s(object));\n\n"
"\tself = %s%s(object);\n\n"
"\tG_OBJECT_CLASS(%s%s_parent_class)->finalize(object);\n"
" %s%s *self;\n\n"
" g_return_if_fail (%sIS_%s (object));\n\n"
" self = %s%s (object);\n\n"
" G_OBJECT_CLASS (%s%s_parent_class)->finalize (object);\n"
"}\n",
class_info->namespace_low, class_info->class_name_low,
class_info->namespace, class_info->class_name,
@ -1036,6 +1032,7 @@ static gboolean create_class(CreateClassDialog *cc_dlg)
text = get_template_class_source(class_info);
editor_insert_text_block(doc->editor, text, 0, -1, 0, TRUE);
g_free(text);
sci_set_current_position(doc->editor->sci, 0, TRUE);
}
if (! utils_str_equal(class_info->header, "") && class_info->type != GEANY_CLASS_TYPE_PHP)
@ -1044,6 +1041,7 @@ static gboolean create_class(CreateClassDialog *cc_dlg)
text = get_template_class_header(class_info);
editor_insert_text_block(doc->editor, text, 0, -1, 0, TRUE);
g_free(text);
sci_set_current_position(doc->editor->sci, 0, TRUE);
}
free_pointers(24, tmp, class_info->namespace, class_info->namespace_up,

View File

@ -791,7 +791,7 @@ static void ui_combo_box_changed(GtkComboBox *combo, gpointer user_data)
{
/* we get this callback on typing as well as choosing an item */
if (gtk_combo_box_get_active(combo) >= 0)
gtk_widget_activate(GTK_BIN(combo)->child);
gtk_widget_activate(gtk_bin_get_child(GTK_BIN(combo)));
}
@ -886,16 +886,6 @@ static GtkWidget *make_toolbar(void)
g_signal_connect(wid, "clicked", G_CALLBACK(on_current_path), NULL);
gtk_container_add(GTK_CONTAINER(toolbar), wid);
if (gtk_check_version(2, 15, 2) != NULL)
{
wid = GTK_WIDGET(gtk_separator_tool_item_new());
gtk_container_add(GTK_CONTAINER(toolbar), wid);
wid = GTK_WIDGET(gtk_tool_button_new_from_stock(GTK_STOCK_CLEAR));
gtk_widget_set_tooltip_text(wid, _("Clear the filter"));
g_signal_connect(wid, "clicked", G_CALLBACK(on_clear_filter), NULL);
gtk_container_add(GTK_CONTAINER(toolbar), wid);
}
return toolbar;
}
@ -909,13 +899,11 @@ static GtkWidget *make_filterbar(void)
label = gtk_label_new(_("Filter:"));
filter_combo = gtk_combo_box_entry_new_text();
filter_entry = GTK_BIN(filter_combo)->child;
filter_entry = gtk_bin_get_child(GTK_BIN(filter_combo));
ui_entry_add_clear_icon(GTK_ENTRY(filter_entry));
g_signal_connect(filter_entry, "icon-release", G_CALLBACK(on_filter_clear), NULL);
if (gtk_check_version(2, 15, 2) == NULL)
{
ui_entry_add_clear_icon(GTK_ENTRY(filter_entry));
g_signal_connect(filter_entry, "icon-release", G_CALLBACK(on_filter_clear), NULL);
}
gtk_widget_set_tooltip_text(filter_entry,
_("Filter your files with the usual wildcards. Separate multiple patterns with a space."));
g_signal_connect(filter_entry, "activate", G_CALLBACK(on_filter_activate), NULL);
@ -1107,7 +1095,7 @@ void plugin_init(GeanyData *data)
path_combo = gtk_combo_box_entry_new_text();
gtk_box_pack_start(GTK_BOX(file_view_vbox), path_combo, FALSE, FALSE, 2);
g_signal_connect(path_combo, "changed", G_CALLBACK(ui_combo_box_changed), NULL);
path_entry = GTK_BIN(path_combo)->child;
path_entry = gtk_bin_get_child(GTK_BIN(path_combo));
g_signal_connect(path_entry, "activate", G_CALLBACK(on_path_entry_activate), NULL);
file_view = gtk_tree_view_new();

View File

@ -805,5 +805,3 @@ void plugin_cleanup(void)
if (config_file != NULL)
g_free(config_file);
}

View File

@ -296,8 +296,8 @@ static gboolean auto_save(gpointer data)
{
doc = document_get_from_page(i);
/* skip current file to save it lastly, skip files without name */
if (doc != cur_doc && cur_doc->file_name != NULL)
/* skip current file (save it last), skip files without name */
if (doc != cur_doc && doc->file_name != NULL)
if (document_save_file(doc, FALSE))
saved_files++;
}
@ -671,7 +671,7 @@ GtkWidget *plugin_configure(GtkDialog *dialog)
g_signal_connect(button, "clicked",
G_CALLBACK(backupcopy_dir_button_clicked_cb), entry_dir);
image = gtk_image_new_from_stock("gtk-open", GTK_ICON_SIZE_BUTTON);
image = gtk_image_new_from_stock(GTK_STOCK_OPEN, GTK_ICON_SIZE_BUTTON);
gtk_container_add(GTK_CONTAINER(button), image);
hbox = gtk_hbox_new(FALSE, 6);

View File

@ -1,3 +1,13 @@
2011-11-06 Frank Lanitz <frank(at)frank(dot)uvena(dot)de>
* mn.po: Added Mongolian translation. Thanks to Цэцэнцэнгэл.
2011-10-30 Frank Lanitz <frlan@frank.uvena.de>
* pl.po: Update of Polish translation. Thanks to Wojciech Świderski.
2011-10-06 Frank Lanitz <frlan@frank.uvena.de>
* sv.po: Update of Swedish translation

5582
po/mn.po Normal file

File diff suppressed because it is too large Load Diff

5304
po/pl.po

File diff suppressed because it is too large Load Diff

View File

@ -9,6 +9,9 @@
#include <stddef.h>
#include <math.h>
#include <vector>
#include <map>
#include <glib.h>
#include <gmodule.h>
#include <gdk/gdk.h>
@ -40,9 +43,37 @@
#define IS_WIDGET_FOCUSSED(w) (GTK_WIDGET_HAS_FOCUS(w))
#endif
#if GTK_CHECK_VERSION(2,22,0)
#define USE_CAIRO 1
#ifdef USE_CAIRO
static cairo_surface_t *CreateSimilarSurface(GdkWindow *window, cairo_content_t content, int width, int height) {
#if GTK_CHECK_VERSION(2,22,0)
return gdk_window_create_similar_surface(window, content, width, height);
#else
cairo_surface_t *window_surface, *surface;
g_return_val_if_fail(GDK_IS_WINDOW(window), NULL);
window_surface = GDK_DRAWABLE_GET_CLASS(window)->ref_cairo_surface(window);
surface = cairo_surface_create_similar(window_surface, content, width, height);
cairo_surface_destroy(window_surface);
return surface;
#endif
}
#endif
static GdkWindow *WindowFromWidget(GtkWidget *w) {
#if GTK_CHECK_VERSION(3,0,0)
return gtk_widget_get_window(w);
#else
return w->window;
#endif
}
#ifdef USE_CAIRO
#define DISABLE_GDK_FONT 1
@ -116,10 +147,17 @@ class FontHandle {
encodingType et;
public:
int ascent;
#ifndef DISABLE_GDK_FONT
GdkFont *pfont;
#endif
PangoFontDescription *pfd;
int characterSet;
FontHandle(GdkFont *pfont_) {
#ifdef DISABLE_GDK_FONT
FontHandle() : et(singleByte), ascent(0), pfd(0), characterSet(-1) {
ResetWidths(et);
}
#else
FontHandle(GdkFont *pfont_=0) {
et = singleByte;
ascent = 0;
pfont = pfont_;
@ -127,10 +165,13 @@ public:
characterSet = -1;
ResetWidths(et);
}
#endif
FontHandle(PangoFontDescription *pfd_, int characterSet_) {
et = singleByte;
ascent = 0;
#ifndef DISABLE_GDK_FONT
pfont = 0;
#endif
pfd = pfd_;
characterSet = characterSet_;
ResetWidths(et);
@ -139,8 +180,8 @@ public:
#ifndef DISABLE_GDK_FONT
if (pfont)
gdk_font_unref(pfont);
#endif
pfont = 0;
#endif
if (pfd)
pango_font_description_free(pfd);
pfd = 0;
@ -183,9 +224,11 @@ static GtkWidget *PWidget(WindowID wid) {
return reinterpret_cast<GtkWidget *>(wid);
}
#if !GTK_CHECK_VERSION(3,0,0)
static GtkWidget *PWidget(Window &w) {
return PWidget(w.GetID());
}
#endif
Point Point::FromLong(long lpoint) {
return Point(
@ -254,6 +297,8 @@ void Palette::WantFind(ColourPair &cp, bool want) {
}
void Palette::Allocate(Window &w) {
#if !GTK_CHECK_VERSION(3,0,0)
// Disable palette on GTK+ 3.
if (allocatedPalette) {
gdk_colormap_free_colors(gtk_widget_get_colormap(PWidget(w)),
reinterpret_cast<GdkColor *>(allocatedPalette),
@ -274,14 +319,17 @@ void Palette::Allocate(Window &w) {
paletteNew[iPal].blue = entries[iPal].desired.GetBlue() * (65535 / 255);
paletteNew[iPal].pixel = entries[iPal].desired.AsLong();
}
#ifndef USE_CAIRO
gdk_colormap_alloc_colors(gtk_widget_get_colormap(PWidget(w)),
paletteNew, allocatedLen, FALSE, TRUE,
successPalette);
#endif
for (iPal = 0; iPal < used; iPal++) {
entries[iPal].allocated.Set(paletteNew[iPal].pixel);
}
}
delete []successPalette;
#endif
}
#ifndef DISABLE_GDK_FONT
@ -671,7 +719,7 @@ FontID FontCached::CreateNewFont(const char *fontName, int characterSet,
}
return new FontHandle(newid);
#else
return new FontHandle(0);
return new FontHandle();
#endif
}
@ -695,6 +743,8 @@ void Font::Release() {
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
// On GTK+ 2.x, SurfaceID is a GdkDrawable* and on GTK+ 3.x, it is a cairo_t*
class SurfaceImpl : public Surface {
encodingType et;
#ifdef USE_CAIRO
@ -736,6 +786,7 @@ public:
void RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back);
void AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated fill, int alphaFill,
ColourAllocated outline, int alphaOutline, int flags);
void DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage);
void Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back);
void Copy(PRectangle rc, Point from, Surface &surfaceSource);
@ -883,7 +934,11 @@ void SurfaceImpl::Init(WindowID wid) {
Release();
PLATFORM_ASSERT(wid);
#ifdef USE_CAIRO
#if GTK_CHECK_VERSION(3,0,0)
GdkWindow *drawable_ = gtk_widget_get_window(PWidget(wid));
#else
GdkDrawable *drawable_ = GDK_DRAWABLE(PWidget(wid)->window);
#endif
if (drawable_) {
context = gdk_cairo_create(drawable_);
PLATFORM_ASSERT(context);
@ -904,14 +959,17 @@ void SurfaceImpl::Init(WindowID wid) {
void SurfaceImpl::Init(SurfaceID sid, WindowID wid) {
PLATFORM_ASSERT(sid);
GdkDrawable *drawable_ = reinterpret_cast<GdkDrawable *>(sid);
Release();
PLATFORM_ASSERT(wid);
#ifdef USE_CAIRO
context = gdk_cairo_create(drawable_);
#if GTK_CHECK_VERSION(3,0,0)
context = cairo_reference(reinterpret_cast<cairo_t *>(sid));
#else
gc = gdk_gc_new(drawable_);
drawable = drawable_;
context = gdk_cairo_create(reinterpret_cast<GdkDrawable *>(sid));
#endif
#else
drawable = reinterpret_cast<GdkDrawable *>(sid);
gc = gdk_gc_new(drawable);
#endif
pcontext = gtk_widget_create_pango_context(PWidget(wid));
layout = pango_layout_new(pcontext);
@ -942,8 +1000,8 @@ void SurfaceImpl::InitPixMap(int width, int height, Surface *surface_, WindowID
PLATFORM_ASSERT(layout);
#ifdef USE_CAIRO
if (height > 0 && width > 0)
psurf = gdk_window_create_similar_surface(
gtk_widget_get_window(PWidget(wid)),
psurf = CreateSimilarSurface(
WindowFromWidget(PWidget(wid)),
CAIRO_CONTENT_COLOR_ALPHA, width, height);
#else
if (height > 0 && width > 0)
@ -974,9 +1032,9 @@ void SurfaceImpl::PenColour(ColourAllocated fore) {
if (context) {
ColourDesired cdFore(fore.AsLong());
cairo_set_source_rgb(context,
cdFore.GetBlue() / 255.0,
cdFore.GetRed() / 255.0,
cdFore.GetGreen() / 255.0,
cdFore.GetRed() / 255.0);
cdFore.GetBlue() / 255.0);
}
#else
if (gc) {
@ -1186,7 +1244,12 @@ void SurfaceImpl::RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAl
static void PathRoundRectangle(cairo_t *context, double left, double top, double width, double height, int radius) {
double degrees = M_PI / 180.0;
#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 2, 0)
cairo_new_sub_path(context);
#else
// First arc is in the top-right corner and starts from a point on the top line
cairo_move_to(context, left + width - radius, top);
#endif
cairo_arc(context, left + width - radius, top + radius, radius, -90 * degrees, 0 * degrees);
cairo_arc(context, left + width - radius, top + height - radius, radius, 0 * degrees, 90 * degrees);
cairo_arc(context, left + radius, top + height - radius, radius, 90 * degrees, 180 * degrees);
@ -1216,8 +1279,6 @@ static guint32 u32FromRGBA(guint8 r, guint8 g, guint8 b, guint8 a) {
return converter.val;
}
#endif
static unsigned int GetRValue(unsigned int co) {
return (co >> 16) & 0xff;
}
@ -1230,24 +1291,34 @@ static unsigned int GetBValue(unsigned int co) {
return co & 0xff;
}
#endif
void SurfaceImpl::AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated fill, int alphaFill,
ColourAllocated outline, int alphaOutline, int flags) {
#ifdef USE_CAIRO
if (context && rc.Width() > 0) {
ColourDesired cdFill(fill.AsLong());
cairo_set_source_rgba(context,
GetRValue(fill.AsLong()) / 255.0,
GetGValue(fill.AsLong()) / 255.0,
GetBValue(fill.AsLong()) / 255.0,
cdFill.GetRed() / 255.0,
cdFill.GetGreen() / 255.0,
cdFill.GetBlue() / 255.0,
alphaFill / 255.0);
PathRoundRectangle(context, rc.left + 1.0, rc.top+1.0, rc.right - rc.left - 2.0, rc.bottom - rc.top - 2.0, cornerSize);
if (cornerSize > 0)
PathRoundRectangle(context, rc.left + 1.0, rc.top + 1.0, rc.right - rc.left - 2.0, rc.bottom - rc.top - 2.0, cornerSize);
else
cairo_rectangle(context, rc.left + 1.0, rc.top + 1.0, rc.right - rc.left - 2.0, rc.bottom - rc.top - 2.0);
cairo_fill(context);
ColourDesired cdOutline(outline.AsLong());
cairo_set_source_rgba(context,
GetRValue(outline.AsLong()) / 255.0,
GetGValue(outline.AsLong()) / 255.0,
GetBValue(outline.AsLong()) / 255.0,
cdOutline.GetRed() / 255.0,
cdOutline.GetGreen() / 255.0,
cdOutline.GetBlue() / 255.0,
alphaOutline / 255.0);
PathRoundRectangle(context, rc.left +0.5, rc.top+0.5, rc.right - rc.left - 1, rc.bottom - rc.top - 1, cornerSize);
if (cornerSize > 0)
PathRoundRectangle(context, rc.left + 0.5, rc.top + 0.5, rc.right - rc.left - 1, rc.bottom - rc.top - 1, cornerSize);
else
cairo_rectangle(context, rc.left + 0.5, rc.top + 0.5, rc.right - rc.left - 1, rc.bottom - rc.top - 1);
cairo_stroke(context);
}
#else
@ -1293,6 +1364,51 @@ void SurfaceImpl::AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated
#endif
}
void SurfaceImpl::DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage) {
if (rc.Width() > width)
rc.left += (rc.Width() - width) / 2;
rc.right = rc.left + width;
if (rc.Height() > height)
rc.top += (rc.Height() - height) / 2;
rc.bottom = rc.top + height;
#ifdef USE_CAIRO
int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
int ucs = stride * height;
std::vector<unsigned char> image(ucs);
for (int y=0; y<height; y++) {
for (int x=0; x<width; x++) {
unsigned char *pixel = &image[0] + y*stride + x * 4;
unsigned char alpha = pixelsImage[3];
pixel[2] = (*pixelsImage++) * alpha / 255;
pixel[1] = (*pixelsImage++) * alpha / 255;
pixel[0] = (*pixelsImage++) * alpha / 255;
pixel[3] = *pixelsImage++;
}
}
cairo_surface_t *psurf = cairo_image_surface_create_for_data(&image[0], CAIRO_FORMAT_ARGB32, width, height, stride);
cairo_set_source_surface(context, psurf, rc.left, rc.top);
cairo_rectangle(context, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top);
cairo_fill(context);
cairo_surface_destroy(psurf);
#else
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data(pixelsImage,
GDK_COLORSPACE_RGB,
TRUE,
8,
width,
height,
width * 4,
NULL,
NULL);
gdk_draw_pixbuf(drawable, gc, pixbuf,
0,0, rc.left,rc.top, width,height, GDK_RGB_DITHER_NORMAL, 0, 0);
g_object_unref(pixbuf);
#endif
}
void SurfaceImpl::Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back) {
PenColour(back);
#ifdef USE_CAIRO
@ -1474,7 +1590,6 @@ void SurfaceImpl::DrawTextBase(PRectangle rc, Font &font_, int ybase, const char
int xText = rc.left;
if (PFont(font_)->pfd) {
char *utfForm = 0;
bool useGFree = false;
if (et == UTF8) {
pango_layout_set_text(layout, s, len);
} else {
@ -1508,11 +1623,7 @@ void SurfaceImpl::DrawTextBase(PRectangle rc, Font &font_, int ybase, const char
#else
gdk_draw_layout_line(drawable, gc, xText, ybase, pll);
#endif
if (useGFree) {
g_free(utfForm);
} else {
delete []utfForm;
}
delete []utfForm;
return;
}
#ifndef DISABLE_GDK_FONT
@ -1690,7 +1801,6 @@ void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positi
}
if (positionsCalculated < 1 ) {
// Either Latin1 or DBCS conversion failed so treat as Latin1.
bool useGFree = false;
SetConverter(PFont(font_)->characterSet);
char *utfForm = UTF8FromIconv(conv, s, len);
if (!utfForm) {
@ -1712,11 +1822,7 @@ void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positi
}
clusterStart = clusterEnd;
}
if (useGFree) {
g_free(utfForm);
} else {
delete []utfForm;
}
delete []utfForm;
PLATFORM_ASSERT(i == lenPositions);
}
}
@ -1792,7 +1898,6 @@ int SurfaceImpl::WidthText(Font &font_, const char *s, int len) {
char *utfForm = 0;
pango_layout_set_font_description(layout, PFont(font_)->pfd);
PangoRectangle pos;
bool useGFree = false;
if (et == UTF8) {
pango_layout_set_text(layout, s, len);
} else {
@ -1815,11 +1920,7 @@ int SurfaceImpl::WidthText(Font &font_, const char *s, int len) {
PangoLayoutLine *pangoLine = pango_layout_get_line(layout,0);
#endif
pango_layout_line_get_extents(pangoLine, NULL, &pos);
if (useGFree) {
g_free(utfForm);
} else {
delete []utfForm;
}
delete []utfForm;
return PANGO_PIXELS(pos.width);
}
#ifndef DISABLE_GDK_FONT
@ -2005,11 +2106,17 @@ PRectangle Window::GetPosition() {
// Before any size allocated pretend its 1000 wide so not scrolled
PRectangle rc(0, 0, 1000, 1000);
if (wid) {
rc.left = PWidget(wid)->allocation.x;
rc.top = PWidget(wid)->allocation.y;
if (PWidget(wid)->allocation.width > 20) {
rc.right = rc.left + PWidget(wid)->allocation.width;
rc.bottom = rc.top + PWidget(wid)->allocation.height;
GtkAllocation allocation;
#if GTK_CHECK_VERSION(3,0,0)
gtk_widget_get_allocation(PWidget(wid), &allocation);
#else
allocation = PWidget(wid)->allocation;
#endif
rc.left = allocation.x;
rc.top = allocation.y;
if (allocation.width > 20) {
rc.right = rc.left + allocation.width;
rc.bottom = rc.top + allocation.height;
}
}
return rc;
@ -2027,7 +2134,7 @@ void Window::SetPosition(PRectangle rc) {
void Window::SetPositionRelative(PRectangle rc, Window relativeTo) {
int ox = 0;
int oy = 0;
gdk_window_get_origin(PWidget(relativeTo.wid)->window, &ox, &oy);
gdk_window_get_origin(WindowFromWidget(PWidget(relativeTo.wid)), &ox, &oy);
ox += rc.left;
if (ox < 0)
ox = 0;
@ -2113,9 +2220,13 @@ void Window::SetCursor(Cursor curs) {
break;
}
if (PWidget(wid)->window)
gdk_window_set_cursor(PWidget(wid)->window, gdkCurs);
if (WindowFromWidget(PWidget(wid)))
gdk_window_set_cursor(WindowFromWidget(PWidget(wid)), gdkCurs);
#if GTK_CHECK_VERSION(3,0,0)
g_object_unref(gdkCurs);
#else
gdk_cursor_unref(gdkCurs);
#endif
}
void Window::SetTitle(const char *s) {
@ -2127,7 +2238,7 @@ void Window::SetTitle(const char *s) {
PRectangle Window::GetMonitorRect(Point pt) {
gint x_offset, y_offset;
gdk_window_get_origin(PWidget(wid)->window, &x_offset, &y_offset);
gdk_window_get_origin(WindowFromWidget(PWidget(wid)), &x_offset, &y_offset);
#if GTK_CHECK_VERSION(2,2,0)
// GTK+ 2.2+
@ -2150,15 +2261,17 @@ PRectangle Window::GetMonitorRect(Point pt) {
#endif
}
typedef std::map<int, RGBAImage*> ImageMap;
struct ListImage {
const char *xpm_data;
const RGBAImage *rgba_data;
GdkPixbuf *pixbuf;
};
static void list_image_free(gpointer, gpointer value, gpointer) {
ListImage *list_image = (ListImage *) value;
if (list_image->pixbuf)
g_object_unref (list_image->pixbuf);
g_object_unref(list_image->pixbuf);
g_free(list_image);
}
@ -2179,7 +2292,7 @@ class ListBoxX : public ListBox {
WindowID scroller;
void *pixhash;
GtkCellRenderer* pixbuf_renderer;
XPMSet xset;
RGBAImageSet images;
int desiredVisibleRows;
unsigned int maxItemCharacters;
unsigned int aveCharWidth;
@ -2211,7 +2324,9 @@ public:
virtual int GetSelection();
virtual int Find(const char *prefix);
virtual void GetValue(int n, char *value, int len);
void RegisterRGBA(int type, RGBAImage *image);
virtual void RegisterImage(int type, const char *xpm_data);
virtual void RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage);
virtual void ClearRegisteredImages();
virtual void SetDoubleClickAction(CallBackAction action, void *data) {
doubleClickAction = action;
@ -2242,24 +2357,47 @@ static gboolean ButtonPress(GtkWidget *, GdkEventButton* ev, gpointer p) {
/* Change the active color to the selected color so the listbox uses the color
scheme that it would use if it had the focus. */
static void StyleSet(GtkWidget *w, GtkStyle*, void*) {
GtkStyle* style;
g_return_if_fail(w != NULL);
/* Copy the selected color to active. Note that the modify calls will cause
recursive calls to this function after the value is updated and w->style to
be set to a new object */
style = gtk_widget_get_style(w);
#if GTK_CHECK_VERSION(3,0,0)
GtkStyleContext *styleContext = gtk_widget_get_style_context(w);
if (styleContext == NULL)
return;
GdkRGBA colourForeSelected;
gtk_style_context_get_color(styleContext, GTK_STATE_FLAG_SELECTED, &colourForeSelected);
GdkRGBA colourForeActive;
gtk_style_context_get_color(styleContext, GTK_STATE_FLAG_ACTIVE, &colourForeActive);
if (!gdk_rgba_equal(&colourForeSelected, &colourForeActive))
gtk_widget_override_color(w, GTK_STATE_FLAG_ACTIVE, &colourForeSelected);
styleContext = gtk_widget_get_style_context(w);
if (styleContext == NULL)
return;
GdkRGBA colourBaseSelected;
gtk_style_context_get_background_color(styleContext, GTK_STATE_FLAG_SELECTED, &colourBaseSelected);
GdkRGBA colourBaseActive;
gtk_style_context_get_background_color(styleContext, GTK_STATE_FLAG_ACTIVE, &colourBaseActive);
if (!gdk_rgba_equal(&colourBaseSelected, &colourBaseActive))
gtk_widget_override_background_color(w, GTK_STATE_FLAG_ACTIVE, &colourBaseSelected);
#else
GtkStyle *style = gtk_widget_get_style(w);
if (style == NULL)
return;
if (!gdk_color_equal(&style->base[GTK_STATE_SELECTED], &style->base[GTK_STATE_ACTIVE]))
gtk_widget_modify_base(w, GTK_STATE_ACTIVE, &style->base[GTK_STATE_SELECTED]);
style = gtk_widget_get_style(w);
if (style == NULL)
return;
if (!gdk_color_equal(&style->text[GTK_STATE_SELECTED], &style->text[GTK_STATE_ACTIVE]))
gtk_widget_modify_text(w, GTK_STATE_ACTIVE, &style->text[GTK_STATE_SELECTED]);
#endif
}
void ListBoxX::Create(Window &, int, Point, int, bool) {
@ -2324,7 +2462,11 @@ void ListBoxX::SetFont(Font &scint_font) {
// Only do for Pango font as there have been crashes for GDK fonts
if (Created() && PFont(scint_font)->pfd) {
// Current font is Pango font
#if GTK_CHECK_VERSION(3,0,0)
gtk_widget_override_font(PWidget(list), PFont(scint_font)->pfd);
#else
gtk_widget_modify_font(PWidget(list), PFont(scint_font)->pfd);
#endif
}
}
@ -2360,14 +2502,27 @@ PRectangle ListBoxX::GetDesiredRect() {
gtk_tree_view_get_column(GTK_TREE_VIEW(list), 0);
gtk_tree_view_column_cell_get_size(column, NULL,
NULL, NULL, &row_width, &row_height);
#if GTK_CHECK_VERSION(3,0,0)
GtkStyleContext *styleContextList = gtk_widget_get_style_context(PWidget(list));
GtkBorder padding;
gtk_style_context_get_padding(styleContextList, GTK_STATE_FLAG_NORMAL, &padding);
height = (rows * row_height
+ padding.top + padding.bottom
+ 2 * (gtk_container_get_border_width(GTK_CONTAINER(PWidget(list))) + 1));
#else
int ythickness = PWidget(list)->style->ythickness;
height = (rows * row_height
+ 2 * (ythickness
+ GTK_CONTAINER(PWidget(list))->border_width + 1));
#endif
gtk_widget_set_size_request(GTK_WIDGET(PWidget(list)), -1, height);
// Get the size of the scroller because we set usize on the window
#if GTK_CHECK_VERSION(3,0,0)
gtk_widget_get_preferred_size(GTK_WIDGET(scroller), NULL, &req);
#else
gtk_widget_size_request(GTK_WIDGET(scroller), &req);
#endif
rc.right = req.width;
rc.bottom = req.height;
@ -2396,25 +2551,21 @@ void ListBoxX::Clear() {
}
static void init_pixmap(ListImage *list_image) {
const char *textForm = list_image->xpm_data;
const char * const * xpm_lineform = reinterpret_cast<const char * const *>(textForm);
const char **xpm_lineformfromtext = 0;
// The XPM data can be either in atext form as will be read from a file
// or in a line form (array of char *) as will be used for images defined in code.
// Test for text form and convert to line form
if ((0 == memcmp(textForm, "/* X", 4)) && (0 == memcmp(textForm, "/* XPM */", 9))) {
// Test done is two parts to avoid possibility of overstepping the memory
// if memcmp implemented strangely. Must be 4 bytes at least at destination.
xpm_lineformfromtext = XPM::LinesFormFromTextForm(textForm);
xpm_lineform = xpm_lineformfromtext;
if (list_image->rgba_data) {
// Drop any existing pixmap/bitmap as data may have changed
if (list_image->pixbuf)
g_object_unref(list_image->pixbuf);
list_image->pixbuf =
gdk_pixbuf_new_from_data(list_image->rgba_data->Pixels(),
GDK_COLORSPACE_RGB,
TRUE,
8,
list_image->rgba_data->GetWidth(),
list_image->rgba_data->GetHeight(),
list_image->rgba_data->GetWidth() * 4,
NULL,
NULL);
}
// Drop any existing pixmap/bitmap as data may have changed
if (list_image->pixbuf)
g_object_unref(list_image->pixbuf);
list_image->pixbuf =
gdk_pixbuf_new_from_xpm_data((const gchar**)xpm_lineform);
delete []xpm_lineformfromtext;
}
#define SPACING 5
@ -2481,11 +2632,17 @@ void ListBoxX::Select(int n) {
// Move the scrollbar to show the selection.
int total = Length();
#if GTK_CHECK_VERSION(3,0,0)
GtkAdjustment *adj =
gtk_scrollable_get_vadjustment(GTK_SCROLLABLE(list));
gfloat value = ((gfloat)n / total) * (gtk_adjustment_get_upper(adj) - gtk_adjustment_get_lower(adj))
+ gtk_adjustment_get_lower(adj) - gtk_adjustment_get_page_size(adj) / 2;
#else
GtkAdjustment *adj =
gtk_tree_view_get_vadjustment(GTK_TREE_VIEW(list));
gfloat value = ((gfloat)n / total) * (adj->upper - adj->lower)
+ adj->lower - adj->page_size / 2;
#endif
// Get cell height
int row_width;
int row_height;
@ -2504,8 +2661,13 @@ void ListBoxX::Select(int n) {
}
// Clamp it.
value = (value < 0)? 0 : value;
#if GTK_CHECK_VERSION(3,0,0)
value = (value > (gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj)))?
(gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj)) : value;
#else
value = (value > (adj->upper - adj->page_size))?
(adj->upper - adj->page_size) : value;
#endif
// Set it.
gtk_adjustment_set_value(adj, value);
@ -2571,13 +2733,8 @@ void ListBoxX::GetValue(int n, char *value, int len) {
#pragma warning(disable: 4127)
#endif
void ListBoxX::RegisterImage(int type, const char *xpm_data) {
g_return_if_fail(xpm_data);
// Saved and use the saved copy so caller's copy can disappear.
xset.Add(type, xpm_data);
XPM *pxpm = xset.Get(type);
xpm_data = reinterpret_cast<const char *>(pxpm->InLinesForm());
void ListBoxX::RegisterRGBA(int type, RGBAImage *image) {
images.Add(type, image);
if (!pixhash) {
pixhash = g_hash_table_new(g_direct_hash, g_direct_equal);
@ -2589,17 +2746,27 @@ void ListBoxX::RegisterImage(int type, const char *xpm_data) {
if (list_image->pixbuf)
g_object_unref(list_image->pixbuf);
list_image->pixbuf = NULL;
list_image->xpm_data = xpm_data;
list_image->rgba_data = image;
} else {
list_image = g_new0(ListImage, 1);
list_image->xpm_data = xpm_data;
list_image->rgba_data = image;
g_hash_table_insert((GHashTable *) pixhash, GINT_TO_POINTER(type),
(gpointer) list_image);
}
}
void ListBoxX::RegisterImage(int type, const char *xpm_data) {
g_return_if_fail(xpm_data);
XPM xpmImage(xpm_data);
RegisterRGBA(type, new RGBAImage(xpmImage));
}
void ListBoxX::RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage) {
RegisterRGBA(type, new RGBAImage(width, height, pixelsImage));
}
void ListBoxX::ClearRegisteredImages() {
xset.Clear();
images.Clear();
}
void ListBoxX::SetList(const char *listText, char separator, char typesep) {
@ -2663,7 +2830,11 @@ void Menu::Show(Point pt, Window &) {
GtkMenu *widget = reinterpret_cast<GtkMenu *>(mid);
gtk_widget_show_all(GTK_WIDGET(widget));
GtkRequisition requisition;
#if GTK_CHECK_VERSION(3,0,0)
gtk_widget_get_preferred_size(GTK_WIDGET(widget), NULL, &requisition);
#else
gtk_widget_size_request(GTK_WIDGET(widget), &requisition);
#endif
if ((pt.x + requisition.width) > screenWidth) {
pt.x = screenWidth - requisition.width;
}
@ -2791,7 +2962,8 @@ bool Platform::IsDBCSLeadByte(int codePage, char ch) {
case 932:
// Shift_jis
return ((uch >= 0x81) && (uch <= 0x9F)) ||
((uch >= 0xE0) && (uch <= 0xEF));
((uch >= 0xE0) && (uch <= 0xFC));
// Lead bytes F0 to FC may be a Microsoft addition.
case 936:
// GBK
return (uch >= 0x81) && (uch <= 0xFE);

File diff suppressed because it is too large Load Diff

View File

@ -16,6 +16,7 @@
#define PLAT_GTK 0
#define PLAT_GTK_WIN32 0
#define PLAT_GTK_MACOSX 0
#define PLAT_MACOSX 0
#define PLAT_WIN 0
#define PLAT_WX 0
@ -38,6 +39,11 @@
#define PLAT_GTK_WIN32 1
#endif
#if defined(__APPLE__)
#undef PLAT_GTK_MACOSX
#define PLAT_GTK_MACOSX 1
#endif
#elif defined(__APPLE__)
#undef PLAT_MACOSX
@ -301,8 +307,11 @@ public:
FontID GetID() { return fid; }
// Alias another font - caller guarantees not to Release
void SetID(FontID fid_) { fid = fid_; }
#if PLAT_WX
void SetAscent(int ascent_) { ascent = ascent_; }
#endif
friend class Surface;
friend class SurfaceImpl;
friend class SurfaceImpl;
};
/**
@ -336,6 +345,7 @@ public:
virtual void RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back)=0;
virtual void AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated fill, int alphaFill,
ColourAllocated outline, int alphaOutline, int flags)=0;
virtual void DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage) = 0;
virtual void Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back)=0;
virtual void Copy(PRectangle rc, Point from, Surface &surfaceSource)=0;
@ -411,8 +421,8 @@ public:
void SetTitle(const char *s);
PRectangle GetMonitorRect(Point pt);
#if PLAT_MACOSX
void SetWindow(void *ref) { windowRef = ref; };
void SetControl(void *_control) { control = _control; };
void SetWindow(void *ref) { windowRef = ref; }
void SetControl(void *_control) { control = _control; }
#endif
private:
Cursor cursorLast;
@ -443,6 +453,7 @@ public:
virtual int Find(const char *prefix)=0;
virtual void GetValue(int n, char *value, int len)=0;
virtual void RegisterImage(int type, const char *xpm_data)=0;
virtual void RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage) = 0;
virtual void ClearRegisteredImages()=0;
virtual void SetDoubleClickAction(CallBackAction, void *)=0;
virtual void SetList(const char* list, char separator, char typesep)=0;

View File

@ -344,6 +344,16 @@
#define SCE_PL_SUB_PROTOTYPE 40
#define SCE_PL_FORMAT_IDENT 41
#define SCE_PL_FORMAT 42
#define SCE_PL_STRING_VAR 43
#define SCE_PL_XLAT 44
#define SCE_PL_REGEX_VAR 54
#define SCE_PL_REGSUBST_VAR 55
#define SCE_PL_BACKTICKS_VAR 57
#define SCE_PL_HERE_QQ_VAR 61
#define SCE_PL_HERE_QX_VAR 62
#define SCE_PL_STRING_QQ_VAR 64
#define SCE_PL_STRING_QX_VAR 65
#define SCE_PL_STRING_QR_VAR 66
#define SCE_RB_DEFAULT 0
#define SCE_RB_ERROR 1
#define SCE_RB_COMMENTLINE 2
@ -408,6 +418,14 @@
#define SCE_L_TAG 2
#define SCE_L_MATH 3
#define SCE_L_COMMENT 4
#define SCE_L_TAG2 5
#define SCE_L_MATH2 6
#define SCE_L_COMMENT2 7
#define SCE_L_VERBATIM 8
#define SCE_L_SHORTCMD 9
#define SCE_L_SPECIAL 10
#define SCE_L_CMDOPT 11
#define SCE_L_ERROR 12
#define SCE_LUA_DEFAULT 0
#define SCE_LUA_COMMENT 1
#define SCE_LUA_COMMENTLINE 2
@ -428,6 +446,7 @@
#define SCE_LUA_WORD6 17
#define SCE_LUA_WORD7 18
#define SCE_LUA_WORD8 19
#define SCE_LUA_LABEL 20
#define SCE_ERR_DEFAULT 0
#define SCE_ERR_PYTHON 1
#define SCE_ERR_GCC 2

View File

@ -124,6 +124,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SC_MARK_LEFTRECT 27
#define SC_MARK_AVAILABLE 28
#define SC_MARK_UNDERLINE 29
#define SC_MARK_RGBAIMAGE 30
#define SC_MARK_CHARACTER 10000
#define SC_MARKNUM_FOLDEREND 25
#define SC_MARKNUM_FOLDEROPENMID 26
@ -136,6 +137,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_MARKERDEFINE 2040
#define SCI_MARKERSETFORE 2041
#define SCI_MARKERSETBACK 2042
#define SCI_MARKERSETBACKSELECTED 2292
#define SCI_MARKERENABLEHIGHLIGHT 2293
#define SCI_MARKERADD 2043
#define SCI_MARKERDELETE 2044
#define SCI_MARKERDELETEALL 2045
@ -245,6 +248,11 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define INDIC_HIDDEN 5
#define INDIC_BOX 6
#define INDIC_ROUNDBOX 7
#define INDIC_STRAIGHTBOX 8
#define INDIC_DASH 9
#define INDIC_DOTS 10
#define INDIC_SQUIGGLELOW 11
#define INDIC_DOTBOX 12
#define INDIC_MAX 31
#define INDIC_CONTAINER 8
#define INDIC0_MASK 0x20
@ -328,6 +336,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_GETSELECTIONSTART 2143
#define SCI_SETSELECTIONEND 2144
#define SCI_GETSELECTIONEND 2145
#define SCI_SETEMPTYSELECTION 2556
#define SCI_SETPRINTMAGNIFICATION 2146
#define SCI_GETPRINTMAGNIFICATION 2147
#define SC_PRINT_NORMAL 0
@ -554,7 +563,9 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_MOVECARETINSIDEVIEW 2401
#define SCI_LINELENGTH 2350
#define SCI_BRACEHIGHLIGHT 2351
#define SCI_BRACEHIGHLIGHTINDICATOR 2498
#define SCI_BRACEBADLIGHT 2352
#define SCI_BRACEBADLIGHTINDICATOR 2499
#define SCI_BRACEMATCH 2353
#define SCI_GETVIEWEOL 2355
#define SCI_SETVIEWEOL 2356
@ -707,6 +718,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_GETKEYSUNICODE 2522
#define SCI_INDICSETALPHA 2523
#define SCI_INDICGETALPHA 2524
#define SCI_INDICSETOUTLINEALPHA 2558
#define SCI_INDICGETOUTLINEALPHA 2559
#define SCI_SETEXTRAASCENT 2525
#define SCI_GETEXTRAASCENT 2526
#define SCI_SETEXTRADESCENT 2527
@ -721,6 +734,10 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_MARGINTEXTCLEARALL 2536
#define SCI_MARGINSETSTYLEOFFSET 2537
#define SCI_MARGINGETSTYLEOFFSET 2538
#define SC_MARGINOPTION_NONE 0
#define SC_MARGINOPTION_SUBLINESELECT 1
#define SCI_SETMARGINOPTIONS 2539
#define SCI_GETMARGINOPTIONS 2557
#define SCI_ANNOTATIONSETTEXT 2540
#define SCI_ANNOTATIONGETTEXT 2541
#define SCI_ANNOTATIONSETSTYLE 2542
@ -792,6 +809,16 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_CHANGELEXERSTATE 2617
#define SCI_CONTRACTEDFOLDNEXT 2618
#define SCI_VERTICALCENTRECARET 2619
#define SCI_MOVESELECTEDLINESUP 2620
#define SCI_MOVESELECTEDLINESDOWN 2621
#define SCI_SETIDENTIFIER 2622
#define SCI_GETIDENTIFIER 2623
#define SCI_RGBAIMAGESETWIDTH 2624
#define SCI_RGBAIMAGESETHEIGHT 2625
#define SCI_MARKERDEFINERGBAIMAGE 2626
#define SCI_REGISTERRGBAIMAGE 2627
#define SCI_SCROLLTOSTART 2628
#define SCI_SCROLLTOEND 2629
#define SCI_STARTRECORD 3001
#define SCI_STOPRECORD 3002
#define SCI_SETLEXER 4001
@ -868,6 +895,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCMOD_CTRL 2
#define SCMOD_ALT 4
#define SCMOD_SUPER 8
#define SCMOD_META 16
#define SCN_STYLENEEDED 2000
#define SCN_CHARADDED 2001
#define SCN_SAVEPOINTREACHED 2002
@ -960,11 +988,22 @@ struct Sci_NotifyHeader {
struct SCNotification {
struct Sci_NotifyHeader nmhdr;
int position; /* SCN_STYLENEEDED, SCN_MODIFIED, SCN_DWELLSTART, SCN_DWELLEND */
int position;
/* SCN_STYLENEEDED, SCN_DOUBLECLICK, SCN_MODIFIED, SCN_MARGINCLICK, */
/* SCN_NEEDSHOWN, SCN_DWELLSTART, SCN_DWELLEND, SCN_CALLTIPCLICK, */
/* SCN_HOTSPOTCLICK, SCN_HOTSPOTDOUBLECLICK, SCN_HOTSPOTRELEASECLICK, */
/* SCN_INDICATORCLICK, SCN_INDICATORRELEASE, */
/* SCN_USERLISTSELECTION, SCN_AUTOCSELECTION */
int ch; /* SCN_CHARADDED, SCN_KEY */
int modifiers; /* SCN_KEY */
int modifiers;
/* SCN_KEY, SCN_DOUBLECLICK, SCN_HOTSPOTCLICK, SCN_HOTSPOTDOUBLECLICK, */
/* SCN_HOTSPOTRELEASECLICK, SCN_INDICATORCLICK, SCN_INDICATORRELEASE, */
int modificationType; /* SCN_MODIFIED */
const char *text; /* SCN_MODIFIED, SCN_USERLISTSELECTION, SCN_AUTOCSELECTION */
const char *text;
/* SCN_MODIFIED, SCN_USERLISTSELECTION, SCN_AUTOCSELECTION, SCN_URIDROPPED */
int length; /* SCN_MODIFIED */
int linesAdded; /* SCN_MODIFIED */
int message; /* SCN_MACRORECORD */
@ -978,7 +1017,7 @@ struct SCNotification {
int x; /* SCN_DWELLSTART, SCN_DWELLEND */
int y; /* SCN_DWELLSTART, SCN_DWELLEND */
int token; /* SCN_MODIFIED with SC_MOD_CONTAINER */
int annotationLinesAdded; /* SC_MOD_CHANGEANNOTATION */
int annotationLinesAdded; /* SCN_MODIFIED with SC_MOD_CHANGEANNOTATION */
int updated; /* SCN_UPDATEUI */
};

View File

@ -268,6 +268,7 @@ val SC_MARK_FULLRECT=26
val SC_MARK_LEFTRECT=27
val SC_MARK_AVAILABLE=28
val SC_MARK_UNDERLINE=29
val SC_MARK_RGBAIMAGE=30
val SC_MARK_CHARACTER=10000
@ -292,6 +293,12 @@ fun void MarkerSetFore=2041(int markerNumber, colour fore)
# Set the background colour used for a particular marker number.
fun void MarkerSetBack=2042(int markerNumber, colour back)
# Set the background colour used for a particular marker number when its folding block is selected.
fun void MarkerSetBackSelected=2292(int markerNumber, colour back)
# Enable/disable highlight for current folding bloc (smallest one that contains the caret)
fun void MarkerEnableHighlight=2293(bool enabled,)
# Add a marker to a line, returning an ID which can be used to find or delete the marker.
fun int MarkerAdd=2043(int line, int markerNumber)
@ -544,6 +551,11 @@ val INDIC_STRIKE=4
val INDIC_HIDDEN=5
val INDIC_BOX=6
val INDIC_ROUNDBOX=7
val INDIC_STRAIGHTBOX=8
val INDIC_DASH=9
val INDIC_DOTS=10
val INDIC_SQUIGGLELOW=11
val INDIC_DOTBOX=12
val INDIC_MAX=31
val INDIC_CONTAINER=8
val INDIC0_MASK=0x20
@ -791,6 +803,9 @@ set void SetSelectionEnd=2144(position pos,)
# Returns the position at the end of the selection.
get position GetSelectionEnd=2145(,)
# Set caret to a position, while removing any existing selection.
fun void SetEmptySelection=2556(position pos,)
# Sets the print magnification added to the point size of each style for printing.
set void SetPrintMagnification=2146(int magnification,)
@ -1440,9 +1455,15 @@ fun int LineLength=2350(int line,)
# Highlight the characters at two positions.
fun void BraceHighlight=2351(position pos1, position pos2)
# Use specified indicator to highlight matching braces instead of changing their style.
fun void BraceHighlightIndicator=2498(bool useBraceHighlightIndicator, int indicator)
# Highlight the character at a position indicating there is no matching brace.
fun void BraceBadLight=2352(position pos,)
# Use specified indicator to highlight non matching brace instead of changing its style.
fun void BraceBadLightIndicator=2499(bool useBraceBadLightIndicator, int indicator)
# Find the position of a matching brace or INVALID_POSITION if no match.
fun position BraceMatch=2353(position pos,)
@ -1884,6 +1905,12 @@ set void IndicSetAlpha=2523(int indicator, int alpha)
# Get the alpha fill colour of the given indicator.
get int IndicGetAlpha=2524(int indicator,)
# Set the alpha outline colour of the given indicator.
set void IndicSetOutlineAlpha=2558(int indicator, int alpha)
# Get the alpha outline colour of the given indicator.
get int IndicGetOutlineAlpha=2559(int indicator,)
# Set extra ascent for each line
set void SetExtraAscent=2525(int extraAscent,)
@ -1926,6 +1953,16 @@ set void MarginSetStyleOffset=2537(int style,)
# Get the start of the range of style numbers used for margin text
get int MarginGetStyleOffset=2538(,)
enu MarginOption=SC_MARGINOPTION_
val SC_MARGINOPTION_NONE=0
val SC_MARGINOPTION_SUBLINESELECT=1
# Set the margin options.
set void SetMarginOptions=2539(int marginOptions,)
# Get the margin options.
get int GetMarginOptions=2557(,)
# Set the annotation text for a line
set void AnnotationSetText=2540(int line, string text)
@ -2106,6 +2143,38 @@ fun int ContractedFoldNext=2618(int lineStart,)
# Centre current line in window.
fun void VerticalCentreCaret=2619(,)
# Move the selected lines up one line, shifting the line above after the selection
fun void MoveSelectedLinesUp=2620(,)
# Move the selected lines down one line, shifting the line below before the selection
fun void MoveSelectedLinesDown=2621(,)
# Set the identifier reported as idFrom in notification messages.
set void SetIdentifier=2622(int identifier,)
# Get the identifier.
get int GetIdentifier=2623(,)
# Set the width for future RGBA image data.
set void RGBAImageSetWidth=2624(int width,)
# Set the height for future RGBA image data.
set void RGBAImageSetHeight=2625(int height,)
# Define a marker from RGBA data.
# It has the width and height from RGBAImageSetWidth/Height
fun void MarkerDefineRGBAImage=2626(int markerNumber, string pixels)
# Register an RGBA image for use in autocompletion lists.
# It has the width and height from RGBAImageSetWidth/Height
fun void RegisterRGBAImage=2627(int type, string pixels)
# Scroll to start of document.
fun void ScrollToStart=2628(,)
# Scroll to end of document.
fun void ScrollToEnd=2629(,)
# Start notifying the container of all key presses and commands.
fun void StartRecord=3001(,)
@ -2247,6 +2316,7 @@ val SCMOD_SHIFT=1
val SCMOD_CTRL=2
val SCMOD_ALT=4
val SCMOD_SUPER=8
val SCMOD_META=16
################################################
# For SciLexer.h
@ -2613,6 +2683,16 @@ val SCE_PL_POD_VERB=31
val SCE_PL_SUB_PROTOTYPE=40
val SCE_PL_FORMAT_IDENT=41
val SCE_PL_FORMAT=42
val SCE_PL_STRING_VAR=43
val SCE_PL_XLAT=44
val SCE_PL_REGEX_VAR=54
val SCE_PL_REGSUBST_VAR=55
val SCE_PL_BACKTICKS_VAR=57
val SCE_PL_HERE_QQ_VAR=61
val SCE_PL_HERE_QX_VAR=62
val SCE_PL_STRING_QQ_VAR=64
val SCE_PL_STRING_QX_VAR=65
val SCE_PL_STRING_QR_VAR=66
# Lexical states for SCLEX_RUBY
lex Ruby=SCLEX_RUBY SCE_RB_
val SCE_RB_DEFAULT=0
@ -2687,6 +2767,14 @@ val SCE_L_COMMAND=1
val SCE_L_TAG=2
val SCE_L_MATH=3
val SCE_L_COMMENT=4
val SCE_L_TAG2=5
val SCE_L_MATH2=6
val SCE_L_COMMENT2=7
val SCE_L_VERBATIM=8
val SCE_L_SHORTCMD=9
val SCE_L_SPECIAL=10
val SCE_L_CMDOPT=11
val SCE_L_ERROR=12
# Lexical states for SCLEX_LUA
lex Lua=SCLEX_LUA SCE_LUA_
val SCE_LUA_DEFAULT=0
@ -2709,6 +2797,7 @@ val SCE_LUA_WORD5=16
val SCE_LUA_WORD6=17
val SCE_LUA_WORD7=18
val SCE_LUA_WORD8=19
val SCE_LUA_LABEL=20
# Lexical states for SCLEX_ERRORLIST
lex ErrorList=SCLEX_ERRORLIST SCE_ERR_
val SCE_ERR_DEFAULT=0
@ -3889,22 +3978,22 @@ evt void SavePointLeft=2003(void)
evt void ModifyAttemptRO=2004(void)
# GTK+ Specific to work around focus and accelerator problems:
evt void Key=2005(int ch, int modifiers)
evt void DoubleClick=2006(void)
evt void UpdateUI=2007(void)
evt void Modified=2008(int position, int modificationType, string text, int length, int linesAdded, int line, int foldLevelNow, int foldLevelPrev)
evt void DoubleClick=2006(int modifiers, int position, int line)
evt void UpdateUI=2007(int updated)
evt void Modified=2008(int position, int modificationType, string text, int length, int linesAdded, int line, int foldLevelNow, int foldLevelPrev, int token, int annotationLinesAdded)
evt void MacroRecord=2009(int message, int wParam, int lParam)
evt void MarginClick=2010(int modifiers, int position, int margin)
evt void NeedShown=2011(int position, int length)
evt void Painted=2013(void)
evt void UserListSelection=2014(int listType, string text)
evt void UserListSelection=2014(int listType, string text, int position)
evt void URIDropped=2015(string text)
evt void DwellStart=2016(int position)
evt void DwellEnd=2017(int position)
evt void DwellStart=2016(int position, int x, int y)
evt void DwellEnd=2017(int position, int x, int y)
evt void Zoom=2018(void)
evt void HotSpotClick=2019(int modifiers, int position)
evt void HotSpotDoubleClick=2020(int modifiers, int position)
evt void CallTipClick=2021(int position)
evt void AutoCSelection=2022(string text)
evt void AutoCSelection=2022(string text, int position)
evt void IndicatorClick=2023(int modifiers, int position)
evt void IndicatorRelease=2024(int modifiers, int position)
evt void AutoCCancelled=2025(void)

View File

@ -1,6 +1,7 @@
// Scintilla source code edit control
/** @file LexBasic.cxx
** Lexer for BlitzBasic and PureBasic.
** Converted to lexer object and added further folding features/properties by "Udo Lechner" <dlchnr(at)gmx(dot)net>
**/
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
@ -21,18 +22,25 @@
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#ifdef _MSC_VER
#pragma warning(disable: 4786)
#endif
#include <string>
#include <map>
#include "ILexer.h"
#include "Scintilla.h"
#include "SciLexer.h"
#include "PropSetSimple.h"
#include "WordList.h"
#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "CharacterSet.h"
#include "LexerModule.h"
#include "OptionSet.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
@ -89,8 +97,213 @@ static int LowerCase(int c)
return c;
}
static void ColouriseBasicDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler, char comment_char) {
static int CheckBlitzFoldPoint(char const *token, int &level) {
if (!strcmp(token, "function") ||
!strcmp(token, "type")) {
level |= SC_FOLDLEVELHEADERFLAG;
return 1;
}
if (!strcmp(token, "end function") ||
!strcmp(token, "end type")) {
return -1;
}
return 0;
}
static int CheckPureFoldPoint(char const *token, int &level) {
if (!strcmp(token, "procedure") ||
!strcmp(token, "enumeration") ||
!strcmp(token, "interface") ||
!strcmp(token, "structure")) {
level |= SC_FOLDLEVELHEADERFLAG;
return 1;
}
if (!strcmp(token, "endprocedure") ||
!strcmp(token, "endenumeration") ||
!strcmp(token, "endinterface") ||
!strcmp(token, "endstructure")) {
return -1;
}
return 0;
}
static int CheckFreeFoldPoint(char const *token, int &level) {
if (!strcmp(token, "function") ||
!strcmp(token, "sub") ||
!strcmp(token, "type")) {
level |= SC_FOLDLEVELHEADERFLAG;
return 1;
}
if (!strcmp(token, "end function") ||
!strcmp(token, "end sub") ||
!strcmp(token, "end type")) {
return -1;
}
return 0;
}
// An individual named option for use in an OptionSet
// Options used for LexerBasic
struct OptionsBasic {
bool fold;
bool foldSyntaxBased;
bool foldCommentExplicit;
std::string foldExplicitStart;
std::string foldExplicitEnd;
bool foldExplicitAnywhere;
bool foldCompact;
OptionsBasic() {
fold = false;
foldSyntaxBased = true;
foldCommentExplicit = false;
foldExplicitStart = "";
foldExplicitEnd = "";
foldExplicitAnywhere = false;
foldCompact = true;
}
};
static const char * const blitzbasicWordListDesc[] = {
"BlitzBasic Keywords",
"user1",
"user2",
"user3",
0
};
static const char * const purebasicWordListDesc[] = {
"PureBasic Keywords",
"PureBasic PreProcessor Keywords",
"user defined 1",
"user defined 2",
0
};
static const char * const freebasicWordListDesc[] = {
"FreeBasic Keywords",
"FreeBasic PreProcessor Keywords",
"user defined 1",
"user defined 2",
0
};
struct OptionSetBasic : public OptionSet<OptionsBasic> {
OptionSetBasic(const char * const wordListDescriptions[]) {
DefineProperty("fold", &OptionsBasic::fold);
DefineProperty("fold.basic.syntax.based", &OptionsBasic::foldSyntaxBased,
"Set this property to 0 to disable syntax based folding.");
DefineProperty("fold.basic.comment.explicit", &OptionsBasic::foldCommentExplicit,
"This option enables folding explicit fold points when using the Basic lexer. "
"Explicit fold points allows adding extra folding by placing a ;{ (BB/PB) or '{ (FB) comment at the start "
"and a ;} (BB/PB) or '} (FB) at the end of a section that should be folded.");
DefineProperty("fold.basic.explicit.start", &OptionsBasic::foldExplicitStart,
"The string to use for explicit fold start points, replacing the standard ;{ (BB/PB) or '{ (FB).");
DefineProperty("fold.basic.explicit.end", &OptionsBasic::foldExplicitEnd,
"The string to use for explicit fold end points, replacing the standard ;} (BB/PB) or '} (FB).");
DefineProperty("fold.basic.explicit.anywhere", &OptionsBasic::foldExplicitAnywhere,
"Set this property to 1 to enable explicit fold points anywhere, not just in line comments.");
DefineProperty("fold.compact", &OptionsBasic::foldCompact);
DefineWordListSets(wordListDescriptions);
}
};
class LexerBasic : public ILexer {
char comment_char;
int (*CheckFoldPoint)(char const *, int &);
WordList keywordlists[4];
OptionsBasic options;
OptionSetBasic osBasic;
public:
LexerBasic(char comment_char_, int (*CheckFoldPoint_)(char const *, int &), const char * const wordListDescriptions[]) :
comment_char(comment_char_),
CheckFoldPoint(CheckFoldPoint_),
osBasic(wordListDescriptions) {
}
~LexerBasic() {
}
void SCI_METHOD Release() {
delete this;
}
int SCI_METHOD Version() const {
return lvOriginal;
}
const char * SCI_METHOD PropertyNames() {
return osBasic.PropertyNames();
}
int SCI_METHOD PropertyType(const char *name) {
return osBasic.PropertyType(name);
}
const char * SCI_METHOD DescribeProperty(const char *name) {
return osBasic.DescribeProperty(name);
}
int SCI_METHOD PropertySet(const char *key, const char *val);
const char * SCI_METHOD DescribeWordListSets() {
return osBasic.DescribeWordListSets();
}
int SCI_METHOD WordListSet(int n, const char *wl);
void SCI_METHOD Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess);
void SCI_METHOD Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess);
void * SCI_METHOD PrivateCall(int, void *) {
return 0;
}
static ILexer *LexerFactoryBlitzBasic() {
return new LexerBasic(';', CheckBlitzFoldPoint, blitzbasicWordListDesc);
}
static ILexer *LexerFactoryPureBasic() {
return new LexerBasic(';', CheckPureFoldPoint, purebasicWordListDesc);
}
static ILexer *LexerFactoryFreeBasic() {
return new LexerBasic('\'', CheckFreeFoldPoint, freebasicWordListDesc );
}
};
int SCI_METHOD LexerBasic::PropertySet(const char *key, const char *val) {
if (osBasic.PropertySet(&options, key, val)) {
return 0;
}
return -1;
}
int SCI_METHOD LexerBasic::WordListSet(int n, const char *wl) {
WordList *wordListN = 0;
switch (n) {
case 0:
wordListN = &keywordlists[0];
break;
case 1:
wordListN = &keywordlists[1];
break;
case 2:
wordListN = &keywordlists[2];
break;
case 3:
wordListN = &keywordlists[3];
break;
}
int firstModification = -1;
if (wordListN) {
WordList wlNew;
wlNew.Set(wl);
if (*wordListN != wlNew) {
wordListN->Set(wl);
firstModification = 0;
}
}
return firstModification;
}
void SCI_METHOD LexerBasic::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
LexAccessor styler(pAccess);
bool wasfirst = true, isfirst = true; // true if first token in a line
styler.StartAt(startPos);
@ -114,7 +327,7 @@ static void ColouriseBasicDoc(unsigned int startPos, int length, int initStyle,
};
sc.GetCurrentLowered(s, sizeof(s));
for (int i = 0; i < 4; i++) {
if (keywordlists[i]->InList(s)) {
if (keywordlists[i].InList(s)) {
sc.ChangeState(kstates[i]);
}
}
@ -205,66 +418,30 @@ static void ColouriseBasicDoc(unsigned int startPos, int length, int initStyle,
sc.Complete();
}
static int CheckBlitzFoldPoint(char const *token, int &level) {
if (!strcmp(token, "function") ||
!strcmp(token, "type")) {
level |= SC_FOLDLEVELHEADERFLAG;
return 1;
}
if (!strcmp(token, "end function") ||
!strcmp(token, "end type")) {
return -1;
}
return 0;
}
static int CheckPureFoldPoint(char const *token, int &level) {
if (!strcmp(token, "procedure") ||
!strcmp(token, "enumeration") ||
!strcmp(token, "interface") ||
!strcmp(token, "structure")) {
level |= SC_FOLDLEVELHEADERFLAG;
return 1;
}
if (!strcmp(token, "endprocedure") ||
!strcmp(token, "endenumeration") ||
!strcmp(token, "endinterface") ||
!strcmp(token, "endstructure")) {
return -1;
}
return 0;
}
void SCI_METHOD LexerBasic::Fold(unsigned int startPos, int length, int /* initStyle */, IDocument *pAccess) {
static int CheckFreeFoldPoint(char const *token, int &level) {
if (!strcmp(token, "function") ||
!strcmp(token, "sub") ||
!strcmp(token, "type")) {
level |= SC_FOLDLEVELHEADERFLAG;
return 1;
}
if (!strcmp(token, "end function") ||
!strcmp(token, "end sub") ||
!strcmp(token, "end type")) {
return -1;
}
return 0;
}
if (!options.fold)
return;
LexAccessor styler(pAccess);
static void FoldBasicDoc(unsigned int startPos, int length,
Accessor &styler, int (*CheckFoldPoint)(char const *, int &)) {
int line = styler.GetLine(startPos);
int level = styler.LevelAt(line);
int go = 0, done = 0;
int endPos = startPos + length;
char word[256];
int wordlen = 0;
int i;
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty();
int cNext = styler[startPos];
// Scan for tokens at the start of the line (they may include
// whitespace, for tokens like "End Function"
for (i = startPos; i < endPos; i++) {
int c = styler.SafeGetCharAt(i);
if (!done && !go) {
for (int i = startPos; i < endPos; i++) {
int c = cNext;
cNext = styler.SafeGetCharAt(i + 1);
bool atEOL = (c == '\r' && cNext != '\n') || (c == '\n');
if (options.foldSyntaxBased && !done && !go) {
if (wordlen) { // are we scanning a token already?
word[wordlen] = static_cast<char>(LowerCase(c));
if (!IsIdentifier(c)) { // done with token
@ -294,8 +471,27 @@ static void FoldBasicDoc(unsigned int startPos, int length,
}
}
}
if (c == '\n') { // line end
if (!done && wordlen == 0 && foldCompact) // line was only space
if (options.foldCommentExplicit && ((styler.StyleAt(i) == SCE_B_COMMENT) || options.foldExplicitAnywhere)) {
if (userDefinedFoldMarkers) {
if (styler.Match(i, options.foldExplicitStart.c_str())) {
level |= SC_FOLDLEVELHEADERFLAG;
go = 1;
} else if (styler.Match(i, options.foldExplicitEnd.c_str())) {
go = -1;
}
} else {
if (c == comment_char) {
if (cNext == '{') {
level |= SC_FOLDLEVELHEADERFLAG;
go = 1;
} else if (cNext == '}') {
go = -1;
}
}
}
}
if (atEOL) { // line end
if (!done && wordlen == 0 && options.foldCompact) // line was only space
level |= SC_FOLDLEVELWHITEFLAG;
if (level != styler.LevelAt(line))
styler.SetLevel(line, level);
@ -311,66 +507,8 @@ static void FoldBasicDoc(unsigned int startPos, int length,
}
}
static void ColouriseBlitzBasicDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler) {
ColouriseBasicDoc(startPos, length, initStyle, keywordlists, styler, ';');
}
LexerModule lmBlitzBasic(SCLEX_BLITZBASIC, LexerBasic::LexerFactoryBlitzBasic, "blitzbasic", blitzbasicWordListDesc);
static void ColourisePureBasicDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler) {
ColouriseBasicDoc(startPos, length, initStyle, keywordlists, styler, ';');
}
static void ColouriseFreeBasicDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler) {
ColouriseBasicDoc(startPos, length, initStyle, keywordlists, styler, '\'');
}
static void FoldBlitzBasicDoc(unsigned int startPos, int length, int,
WordList *[], Accessor &styler) {
FoldBasicDoc(startPos, length, styler, CheckBlitzFoldPoint);
}
static void FoldPureBasicDoc(unsigned int startPos, int length, int,
WordList *[], Accessor &styler) {
FoldBasicDoc(startPos, length, styler, CheckPureFoldPoint);
}
static void FoldFreeBasicDoc(unsigned int startPos, int length, int,
WordList *[], Accessor &styler) {
FoldBasicDoc(startPos, length, styler, CheckFreeFoldPoint);
}
static const char * const blitzbasicWordListDesc[] = {
"BlitzBasic Keywords",
"user1",
"user2",
"user3",
0
};
static const char * const purebasicWordListDesc[] = {
"PureBasic Keywords",
"PureBasic PreProcessor Keywords",
"user defined 1",
"user defined 2",
0
};
static const char * const freebasicWordListDesc[] = {
"FreeBasic Keywords",
"FreeBasic PreProcessor Keywords",
"user defined 1",
"user defined 2",
0
};
LexerModule lmBlitzBasic(SCLEX_BLITZBASIC, ColouriseBlitzBasicDoc, "blitzbasic",
FoldBlitzBasicDoc, blitzbasicWordListDesc);
LexerModule lmPureBasic(SCLEX_PUREBASIC, ColourisePureBasicDoc, "purebasic",
FoldPureBasicDoc, purebasicWordListDesc);
LexerModule lmFreeBasic(SCLEX_FREEBASIC, ColouriseFreeBasicDoc, "freebasic",
FoldFreeBasicDoc, freebasicWordListDesc);
LexerModule lmPureBasic(SCLEX_PUREBASIC, LexerBasic::LexerFactoryPureBasic, "purebasic", purebasicWordListDesc);
LexerModule lmFreeBasic(SCLEX_FREEBASIC, LexerBasic::LexerFactoryFreeBasic, "freebasic", freebasicWordListDesc);

View File

@ -208,6 +208,14 @@ static void ColouriseCOBOLDoc(unsigned int startPos, int length, int initStyle,
if (isCOBOLwordstart(ch) || (ch == '$' && isascii(chNext) && isalpha(chNext))) {
ColourTo(styler, i-1, state);
state = SCE_C_IDENTIFIER;
} else if (column == 6 && ch == '*') {
// Cobol comment line: asterisk in column 7.
ColourTo(styler, i-1, state);
state = SCE_C_COMMENTLINE;
} else if (ch == '*' && chNext == '>') {
// Cobol inline comment: asterisk, followed by greater than.
ColourTo(styler, i-1, state);
state = SCE_C_COMMENTLINE;
} else if (column == 0 && ch == '*' && chNext != '*') {
ColourTo(styler, i-1, state);
state = SCE_C_COMMENTLINE;

View File

@ -324,6 +324,7 @@ class LexerCPP : public ILexer {
OptionsCPP options;
OptionSetCPP osCPP;
SparseState<std::string> rawStringTerminators;
enum { activeFlag = 0x40 };
public:
LexerCPP(bool caseSensitive_) :
caseSensitive(caseSensitive_),
@ -368,7 +369,9 @@ public:
static ILexer *LexerFactoryCPPInsensitive() {
return new LexerCPP(false);
}
static int MaskActive(int style) {
return style & ~activeFlag;
}
void EvaluateTokens(std::vector<std::string> &tokens);
bool EvaluateExpression(const std::string &expr, const std::map<std::string, std::string> &preprocessorDefinitions);
};
@ -432,7 +435,7 @@ int SCI_METHOD LexerCPP::WordListSet(int n, const char *wl) {
struct After {
int line;
After(int line_) : line(line_) {}
bool operator() (PPDefinition &p) const {
bool operator()(PPDefinition &p) const {
return p.line > line;
}
};
@ -508,11 +511,10 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
preprocessorDefinitions[itDef->key] = itDef->value;
}
const int maskActivity = 0x3F;
std::string rawStringTerminator = rawStringTerminators.ValueAt(lineCurrent-1);
SparseState<std::string> rawSTNew(lineCurrent);
int activitySet = preproc.IsInactive() ? 0x40 : 0;
int activitySet = preproc.IsInactive() ? activeFlag : 0;
for (; sc.More(); sc.Forward()) {
@ -528,7 +530,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
lastWordWasUUID = false;
isIncludePreprocessor = false;
if (preproc.IsInactive()) {
activitySet = 0x40;
activitySet = activeFlag;
sc.SetState(sc.state | activitySet);
}
if (activitySet) {
@ -563,7 +565,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
const bool atLineEndBeforeSwitch = sc.atLineEnd;
// Determine if the current state should terminate.
switch (sc.state & maskActivity) {
switch (MaskActive(sc.state)) {
case SCE_C_OPERATOR:
sc.SetState(SCE_C_DEFAULT|activitySet);
break;
@ -739,7 +741,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
}
break;
case SCE_C_TRIPLEVERBATIM:
if (sc.Match ("\"\"\"")) {
if (sc.Match("\"\"\"")) {
while (sc.Match('"')) {
sc.Forward();
}
@ -759,7 +761,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
}
// Determine if a new state should be entered.
if ((sc.state & maskActivity) == SCE_C_DEFAULT) {
if (MaskActive(sc.state) == SCE_C_DEFAULT) {
if (sc.Match('@', '\"')) {
sc.SetState(SCE_C_VERBATIM|activitySet);
sc.Forward();
@ -801,15 +803,20 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
sc.SetState(SCE_C_REGEX|activitySet); // JavaScript's RegEx
} else if (sc.ch == '\"') {
if (sc.chPrev == 'R') {
sc.SetState(SCE_C_STRINGRAW|activitySet);
rawStringTerminator = ")";
for (int termPos = sc.currentPos + 1;;termPos++) {
char chTerminator = styler.SafeGetCharAt(termPos, '(');
if (chTerminator == '(')
break;
rawStringTerminator += chTerminator;
styler.Flush();
if (MaskActive(styler.StyleAt(sc.currentPos - 1)) == SCE_C_STRINGRAW) {
sc.SetState(SCE_C_STRINGRAW|activitySet);
rawStringTerminator = ")";
for (int termPos = sc.currentPos + 1;; termPos++) {
char chTerminator = styler.SafeGetCharAt(termPos, '(');
if (chTerminator == '(')
break;
rawStringTerminator += chTerminator;
}
rawStringTerminator += '\"';
} else {
sc.SetState(SCE_C_STRING|activitySet);
}
rawStringTerminator += '\"';
} else {
sc.SetState(SCE_C_STRING|activitySet);
}
@ -844,12 +851,12 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
} else if (sc.Match("else")) {
if (!preproc.CurrentIfTaken()) {
preproc.InvertCurrentLevel();
activitySet = preproc.IsInactive() ? 0x40 : 0;
activitySet = preproc.IsInactive() ? activeFlag : 0;
if (!activitySet)
sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
} else if (!preproc.IsInactive()) {
preproc.InvertCurrentLevel();
activitySet = preproc.IsInactive() ? 0x40 : 0;
activitySet = preproc.IsInactive() ? activeFlag : 0;
if (!activitySet)
sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
}
@ -861,19 +868,19 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
bool ifGood = EvaluateExpression(restOfLine, preprocessorDefinitions);
if (ifGood) {
preproc.InvertCurrentLevel();
activitySet = preproc.IsInactive() ? 0x40 : 0;
activitySet = preproc.IsInactive() ? activeFlag : 0;
if (!activitySet)
sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
}
} else if (!preproc.IsInactive()) {
preproc.InvertCurrentLevel();
activitySet = preproc.IsInactive() ? 0x40 : 0;
activitySet = preproc.IsInactive() ? activeFlag : 0;
if (!activitySet)
sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
}
} else if (sc.Match("endif")) {
preproc.EndSection();
activitySet = preproc.IsInactive() ? 0x40 : 0;
activitySet = preproc.IsInactive() ? activeFlag : 0;
sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
} else if (sc.Match("define")) {
if (options.updatePreprocessor && !preproc.IsInactive()) {
@ -933,15 +940,15 @@ void SCI_METHOD LexerCPP::Fold(unsigned int startPos, int length, int initStyle,
int levelMinCurrent = levelCurrent;
int levelNext = levelCurrent;
char chNext = styler[startPos];
int styleNext = styler.StyleAt(startPos);
int style = initStyle;
int styleNext = MaskActive(styler.StyleAt(startPos));
int style = MaskActive(initStyle);
const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty();
for (unsigned int i = startPos; i < endPos; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
int stylePrev = style;
style = styleNext;
styleNext = styler.StyleAt(i + 1);
styleNext = MaskActive(styler.StyleAt(i + 1));
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
if (options.foldComment && options.foldCommentMultiline && IsStreamCommentStyle(style)) {
if (!IsStreamCommentStyle(stylePrev) && (stylePrev != SCE_C_COMMENTLINEDOC)) {

View File

@ -57,7 +57,7 @@ inline bool IsOperator(int ch) {
}
static void GetTextSegment(Accessor &styler, unsigned int start, unsigned int end, char *s, size_t len) {
size_t i = 0;
unsigned int i = 0;
for (; (i < end - start + 1) && (i < len-1); i++) {
s[i] = static_cast<char>(MakeLowerCase(styler[start + i]));
}
@ -66,7 +66,7 @@ static void GetTextSegment(Accessor &styler, unsigned int start, unsigned int en
static const char *GetNextWord(Accessor &styler, unsigned int start, char *s, size_t sLen) {
size_t i = 0;
unsigned int i = 0;
for (; i < sLen-1; i++) {
char ch = static_cast<char>(styler.SafeGetCharAt(start + i));
if ((i == 0) && !IsAWordStart(ch))
@ -318,19 +318,19 @@ static int classifyTagHTML(unsigned int start, unsigned int end,
static void classifyWordHTJS(unsigned int start, unsigned int end,
WordList &keywords, Accessor &styler, script_mode inScriptType) {
char s[30 + 1];
unsigned int i = 0;
for (; i < end - start + 1 && i < 30; i++) {
s[i] = styler[start + i];
}
s[i] = '\0';
char chAttr = SCE_HJ_WORD;
bool wordIsNumber = IsADigit(styler[start]) || (styler[start] == '.');
if (wordIsNumber)
bool wordIsNumber = IsADigit(s[0]) || ((s[0] == '.') && IsADigit(s[1]));
if (wordIsNumber) {
chAttr = SCE_HJ_NUMBER;
else {
char s[30 + 1];
unsigned int i = 0;
for (; i < end - start + 1 && i < 30; i++) {
s[i] = styler[start + i];
}
s[i] = '\0';
if (keywords.InList(s))
chAttr = SCE_HJ_KEYWORD;
} else if (keywords.InList(s)) {
chAttr = SCE_HJ_KEYWORD;
}
styler.ColourTo(end, statePrintForState(chAttr, inScriptType));
}
@ -356,7 +356,7 @@ static int classifyWordHTVB(unsigned int start, unsigned int end, WordList &keyw
return SCE_HB_DEFAULT;
}
static void classifyWordHTPy(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord, script_mode inScriptType) {
static void classifyWordHTPy(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord, script_mode inScriptType, bool isMako) {
bool wordIsNumber = IsADigit(styler[start]);
char s[30 + 1];
unsigned int i = 0;
@ -373,6 +373,8 @@ static void classifyWordHTPy(unsigned int start, unsigned int end, WordList &key
chAttr = SCE_HP_NUMBER;
else if (keywords.InList(s))
chAttr = SCE_HP_WORD;
else if (isMako && 0 == strcmp(s, "block"))
chAttr = SCE_HP_WORD;
styler.ColourTo(end, statePrintForState(chAttr, inScriptType));
strcpy(prevWord, s);
}
@ -494,7 +496,10 @@ static bool isMakoBlockEnd(const int ch, const int chNext, const char *blockType
(0 == strcmp(blockType, "page"))) {
return ((ch == '/') && (chNext == '>'));
} else if (0 == strcmp(blockType, "%")) {
return isLineEnd(ch);
if (ch == '/' && isLineEnd(chNext))
return 1;
else
return isLineEnd(ch);
} else if (0 == strcmp(blockType, "{")) {
return ch == '}';
} else {
@ -588,6 +593,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
int state = stateForPrintState(StateToPrint);
char makoBlockType[200];
makoBlockType[0] = '\0';
int makoComment = 0;
char djangoBlockType[2];
djangoBlockType[0] = '\0';
@ -754,15 +760,15 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
} else if (styler.Match(j, "end")) {
levelCurrent--;
}
} else if ((ch == '{') || (ch == '}') || (foldComment && (ch == '/') && (chNext == '*')) ) {
levelCurrent += ((ch == '{') || (ch == '/') ) ? 1 : -1;
} else if ((ch == '{') || (ch == '}') || (foldComment && (ch == '/') && (chNext == '*'))) {
levelCurrent += (((ch == '{') || (ch == '/')) ? 1 : -1);
}
} else if (((state == SCE_HPHP_COMMENT) || (state == SCE_HJ_COMMENT)) && foldComment && (ch == '*') && (chNext == '/')) {
levelCurrent--;
}
break;
case eScriptPython:
if (state != SCE_HP_COMMENTLINE) {
if (state != SCE_HP_COMMENTLINE && !isMako) {
if ((ch == ':') && ((chNext == '\n') || (chNext == '\r' && chNext2 == '\n'))) {
levelCurrent++;
} else if ((ch == '\n') && !((chNext == '\r') && (chNext2 == '\n')) && (chNext != '\n')) {
@ -818,6 +824,18 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
lineStartVisibleChars = 0;
}
// handle start of Mako comment line
if (isMako && ch == '#' && chNext == '#') {
makoComment = 1;
}
// handle end of Mako comment line
else if (isMako && makoComment && (ch == '\r' || ch == '\n')) {
makoComment = 0;
styler.ColourTo(i, SCE_HP_COMMENTLINE);
state = SCE_HP_DEFAULT;
}
// Allow falling through to mako handling code if newline is going to end a block
if (((ch == '\r' && chNext != '\n') || (ch == '\n')) &&
(!isMako || (0 != strcmp(makoBlockType, "%")))) {
@ -882,7 +900,8 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
(state != SCE_HPHP_COMMENTLINE) &&
(ch == '<') &&
(chNext == '?') &&
!IsScriptCommentState(state) ) {
!IsScriptCommentState(state)) {
beforeLanguage = scriptLanguage;
scriptLanguage = segIsScriptingIndicator(styler, i + 2, i + 6, eScriptPHP);
if (scriptLanguage != eScriptPHP && isStringState(state)) continue;
styler.ColourTo(i - 1, StateToPrint);
@ -911,9 +930,10 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
// handle the start Mako template Python code
else if (isMako && scriptLanguage == eScriptNone && ((ch == '<' && chNext == '%') ||
(lineStartVisibleChars == 1 && ch == '%') ||
(lineStartVisibleChars == 1 && ch == '/' && chNext == '%') ||
(ch == '$' && chNext == '{') ||
(ch == '<' && chNext == '/' && chNext2 == '%'))) {
if (ch == '%')
if (ch == '%' || ch == '/')
strcpy(makoBlockType, "%");
else if (ch == '$')
strcpy(makoBlockType, "{");
@ -938,12 +958,10 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
state = SCE_HP_START;
scriptLanguage = eScriptPython;
styler.ColourTo(i, SCE_H_ASP);
if (foldHTMLPreprocessor && ch == '<')
levelCurrent++;
if (ch != '%' && ch != '$') {
i += strlen(makoBlockType);
visibleChars += strlen(makoBlockType);
if (ch != '%' && ch != '$' && ch != '/') {
i += static_cast<int>(strlen(makoBlockType));
visibleChars += static_cast<int>(strlen(makoBlockType));
if (keywords4.InList(makoBlockType))
styler.ColourTo(i, SCE_HP_WORD);
else
@ -954,6 +972,36 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
continue;
}
// handle the start/end of Django comment
else if (isDjango && state != SCE_H_COMMENT && (ch == '{' && chNext == '#')) {
styler.ColourTo(i - 1, StateToPrint);
beforePreProc = state;
beforeLanguage = scriptLanguage;
if (inScriptType == eNonHtmlScript)
inScriptType = eNonHtmlScriptPreProc;
else
inScriptType = eNonHtmlPreProc;
i += 1;
visibleChars += 1;
scriptLanguage = eScriptComment;
state = SCE_H_COMMENT;
styler.ColourTo(i, SCE_H_ASP);
ch = static_cast<unsigned char>(styler.SafeGetCharAt(i));
continue;
} else if (isDjango && state == SCE_H_COMMENT && (ch == '#' && chNext == '}')) {
styler.ColourTo(i - 1, StateToPrint);
i += 1;
visibleChars += 1;
styler.ColourTo(i, SCE_H_ASP);
state = beforePreProc;
if (inScriptType == eNonHtmlScriptPreProc)
inScriptType = eNonHtmlScript;
else
inScriptType = eHtml;
scriptLanguage = beforeLanguage;
continue;
}
// handle the start Django template code
else if (isDjango && scriptLanguage != eScriptPython && (ch == '{' && (chNext == '%' || chNext == '{'))) {
if (chNext == '%')
@ -1024,7 +1072,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
(ch == '!') &&
(StateToPrint != SCE_H_CDATA) &&
(!IsCommentState(StateToPrint)) &&
(!IsScriptCommentState(StateToPrint)) ) {
(!IsScriptCommentState(StateToPrint))) {
beforePreProc = state;
styler.ColourTo(i - 2, StateToPrint);
if ((chNext == '-') && (chNext2 == '-')) {
@ -1054,7 +1102,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
styler.GetStartSegment(), i - 1, aspScript);
}
if (state == SCE_HP_WORD) {
classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType);
classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType, isMako);
} else {
styler.ColourTo(i - 1, StateToPrint);
}
@ -1062,7 +1110,11 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
i++;
visibleChars++;
}
if (0 != strcmp(makoBlockType, "%")) {
else if (0 == strcmp(makoBlockType, "%") && ch == '/') {
i++;
visibleChars++;
}
if (0 != strcmp(makoBlockType, "%") || ch == '/') {
styler.ColourTo(i, SCE_H_ASP);
}
state = beforePreProc;
@ -1070,9 +1122,6 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
inScriptType = eNonHtmlScript;
else
inScriptType = eHtml;
if (foldHTMLPreprocessor && ch != '\n' && ch != '\r') {
levelCurrent--;
}
scriptLanguage = eScriptNone;
continue;
}
@ -1087,7 +1136,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
styler.GetStartSegment(), i - 1, aspScript);
}
if (state == SCE_HP_WORD) {
classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType);
classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType, isMako);
} else {
styler.ColourTo(i - 1, StateToPrint);
}
@ -1121,7 +1170,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
classifyWordHTVB(styler.GetStartSegment(), i - 1, keywords3, styler, inScriptType);
break;
case SCE_HP_WORD:
classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType);
classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType, isMako);
break;
case SCE_HPHP_WORD:
classifyWordHTPHP(styler.GetStartSegment(), i - 1, keywords5, styler);
@ -1154,7 +1203,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
if (foldHTMLPreprocessor && (scriptLanguage != eScriptXML)) {
levelCurrent--;
}
scriptLanguage = eScriptNone;
scriptLanguage = beforeLanguage;
continue;
}
/////////////////////////////////////
@ -1783,7 +1832,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
break;
case SCE_HP_WORD:
if (!IsAWordChar(ch)) {
classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType);
classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType, isMako);
state = SCE_HP_DEFAULT;
if (ch == '#') {
state = SCE_HP_COMMENTLINE;
@ -1934,7 +1983,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
styler.ColourTo(i, StateToPrint);
state = SCE_HPHP_DEFAULT;
} else if (isLineEnd(chPrev)) {
const int psdLength = strlen(phpStringDelimiter);
const int psdLength = static_cast<int>(strlen(phpStringDelimiter));
const char chAfterPsd = styler.SafeGetCharAt(i + psdLength);
const char chAfterPsd2 = styler.SafeGetCharAt(i + psdLength + 1);
if (isLineEnd(chAfterPsd) ||
@ -1957,7 +2006,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
state = SCE_HPHP_DEFAULT;
}
} else if (isLineEnd(chPrev) && styler.Match(i, phpStringDelimiter)) {
const int psdLength = strlen(phpStringDelimiter);
const int psdLength = static_cast<int>(strlen(phpStringDelimiter));
const char chAfterPsd = styler.SafeGetCharAt(i + psdLength);
const char chAfterPsd2 = styler.SafeGetCharAt(i + psdLength + 1);
if (isLineEnd(chAfterPsd) ||
@ -2072,7 +2121,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
classifyWordHTVB(styler.GetStartSegment(), lengthDoc - 1, keywords3, styler, inScriptType);
break;
case SCE_HP_WORD:
classifyWordHTPy(styler.GetStartSegment(), lengthDoc - 1, keywords4, styler, prevWord, inScriptType);
classifyWordHTPy(styler.GetStartSegment(), lengthDoc - 1, keywords4, styler, prevWord, inScriptType, isMako);
break;
case SCE_HPHP_WORD:
classifyWordHTPHP(styler.GetStartSegment(), lengthDoc - 1, keywords5, styler);

View File

@ -59,10 +59,11 @@ static void ColouriseLuaDoc(
// Accepts accented characters
CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true);
CharacterSet setWord(CharacterSet::setAlphaNum, "_", 0x80, true);
// Not exactly following number definition (several dots are seen as OK, etc.)
// but probably enough in most cases.
CharacterSet setNumber(CharacterSet::setDigits, ".-+abcdefABCDEF");
// but probably enough in most cases. [pP] is for hex floats.
CharacterSet setNumber(CharacterSet::setDigits, ".-+abcdefpABCDEFP");
CharacterSet setExponent(CharacterSet::setNone, "eEpP");
CharacterSet setLuaOperator(CharacterSet::setNone, "*/-+()={}~[];<>,.^%:#");
CharacterSet setEscapeSkip(CharacterSet::setNone, "\"'\\");
@ -70,12 +71,16 @@ static void ColouriseLuaDoc(
// Initialize long string [[ ... ]] or block comment --[[ ... ]] nesting level,
// if we are inside such a string. Block comment was introduced in Lua 5.0,
// blocks with separators [=[ ... ]=] in Lua 5.1.
// Continuation of a string (\z whitespace escaping) is controlled by stringWs.
int nestLevel = 0;
int sepCount = 0;
if (initStyle == SCE_LUA_LITERALSTRING || initStyle == SCE_LUA_COMMENT) {
int stringWs = 0;
if (initStyle == SCE_LUA_LITERALSTRING || initStyle == SCE_LUA_COMMENT ||
initStyle == SCE_LUA_STRING || initStyle == SCE_LUA_CHARACTER) {
int lineState = styler.GetLineState(currentLine - 1);
nestLevel = lineState >> 8;
nestLevel = lineState >> 9;
sepCount = lineState & 0xFF;
stringWs = lineState & 0x100;
}
// Do not leak onto next line
@ -95,8 +100,10 @@ static void ColouriseLuaDoc(
switch (sc.state) {
case SCE_LUA_LITERALSTRING:
case SCE_LUA_COMMENT:
// Inside a literal string or block comment, we set the line state
styler.SetLineState(currentLine, (nestLevel << 8) | sepCount);
case SCE_LUA_STRING:
case SCE_LUA_CHARACTER:
// Inside a literal string, block comment or string, we set the line state
styler.SetLineState(currentLine, (nestLevel << 9) | stringWs | sepCount);
break;
default:
// Reset the line state
@ -123,21 +130,91 @@ static void ColouriseLuaDoc(
// Determine if the current state should terminate.
if (sc.state == SCE_LUA_OPERATOR) {
if (sc.ch == ':' && sc.chPrev == ':') { // :: <label> :: forward scan
sc.Forward();
int ln = 0, maxln = startPos + length - sc.currentPos;
int c;
while (ln < maxln) { // determine line extent
c = sc.GetRelative(ln);
if (c == '\r' || c == '\n')
break;
ln++;
}
maxln = ln; ln = 0;
while (ln < maxln) { // skip over spaces/tabs
if (!IsASpaceOrTab(sc.GetRelative(ln)))
break;
ln++;
}
int ws1 = ln;
if (setWordStart.Contains(sc.GetRelative(ln))) {
int i = 0;
char s[100];
while (ln < maxln) { // get potential label
c = sc.GetRelative(ln);
if (!setWord.Contains(c))
break;
if (i < 90)
s[i++] = c;
ln++;
}
s[i] = '\0'; int lbl = ln;
if (!keywords.InList(s)) {
while (ln < maxln) { // skip over spaces/tabs
if (!IsASpaceOrTab(sc.GetRelative(ln)))
break;
ln++;
}
int ws2 = ln - lbl;
if (sc.GetRelative(ln) == ':' && sc.GetRelative(ln + 1) == ':') {
// final :: found, complete valid label construct
sc.ChangeState(SCE_LUA_LABEL);
if (ws1) {
sc.SetState(SCE_LUA_DEFAULT);
sc.Forward(ws1);
}
sc.SetState(SCE_LUA_LABEL);
sc.Forward(lbl - ws1);
if (ws2) {
sc.SetState(SCE_LUA_DEFAULT);
sc.Forward(ws2);
}
sc.SetState(SCE_LUA_LABEL);
sc.Forward(2);
}
}
}
}
sc.SetState(SCE_LUA_DEFAULT);
} else if (sc.state == SCE_LUA_NUMBER) {
// We stop the number definition on non-numerical non-dot non-eE non-sign non-hexdigit char
// We stop the number definition on non-numerical non-dot non-eEpP non-sign non-hexdigit char
if (!setNumber.Contains(sc.ch)) {
sc.SetState(SCE_LUA_DEFAULT);
} else if (sc.ch == '-' || sc.ch == '+') {
if (sc.chPrev != 'E' && sc.chPrev != 'e')
if (!setExponent.Contains(sc.chPrev))
sc.SetState(SCE_LUA_DEFAULT);
}
} else if (sc.state == SCE_LUA_IDENTIFIER) {
if (!setWord.Contains(sc.ch) || sc.Match('.', '.')) {
if (!(setWord.Contains(sc.ch) || sc.ch == '.') || sc.Match('.', '.')) {
char s[100];
sc.GetCurrent(s, sizeof(s));
if (keywords.InList(s)) {
sc.ChangeState(SCE_LUA_WORD);
if (strcmp(s, "goto") == 0) { // goto <label> forward scan
sc.SetState(SCE_LUA_DEFAULT);
while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd)
sc.Forward();
if (setWordStart.Contains(sc.ch)) {
sc.SetState(SCE_LUA_LABEL);
sc.Forward();
while (setWord.Contains(sc.ch))
sc.Forward();
sc.GetCurrent(s, sizeof(s));
if (keywords.InList(s))
sc.ChangeState(SCE_LUA_WORD);
}
sc.SetState(SCE_LUA_DEFAULT);
}
} else if (keywords2.InList(s)) {
sc.ChangeState(SCE_LUA_WORD2);
} else if (keywords3.InList(s)) {
@ -160,24 +237,38 @@ static void ColouriseLuaDoc(
sc.ForwardSetState(SCE_LUA_DEFAULT);
}
} else if (sc.state == SCE_LUA_STRING) {
if (stringWs) {
if (!IsASpace(sc.ch))
stringWs = 0;
}
if (sc.ch == '\\') {
if (setEscapeSkip.Contains(sc.chNext)) {
sc.Forward();
} else if (sc.chNext == 'z') {
sc.Forward();
stringWs = 0x100;
}
} else if (sc.ch == '\"') {
sc.ForwardSetState(SCE_LUA_DEFAULT);
} else if (sc.atLineEnd) {
} else if (stringWs == 0 && sc.atLineEnd) {
sc.ChangeState(SCE_LUA_STRINGEOL);
sc.ForwardSetState(SCE_LUA_DEFAULT);
}
} else if (sc.state == SCE_LUA_CHARACTER) {
if (stringWs) {
if (!IsASpace(sc.ch))
stringWs = 0;
}
if (sc.ch == '\\') {
if (setEscapeSkip.Contains(sc.chNext)) {
sc.Forward();
} else if (sc.chNext == 'z') {
sc.Forward();
stringWs = 0x100;
}
} else if (sc.ch == '\'') {
sc.ForwardSetState(SCE_LUA_DEFAULT);
} else if (sc.atLineEnd) {
} else if (stringWs == 0 && sc.atLineEnd) {
sc.ChangeState(SCE_LUA_STRINGEOL);
sc.ForwardSetState(SCE_LUA_DEFAULT);
}
@ -214,8 +305,10 @@ static void ColouriseLuaDoc(
sc.SetState(SCE_LUA_IDENTIFIER);
} else if (sc.ch == '\"') {
sc.SetState(SCE_LUA_STRING);
stringWs = 0;
} else if (sc.ch == '\'') {
sc.SetState(SCE_LUA_CHARACTER);
stringWs = 0;
} else if (sc.ch == '[') {
sepCount = LongDelimCheck(sc);
if (sepCount == 0) {
@ -246,7 +339,7 @@ static void ColouriseLuaDoc(
}
}
if (setWord.Contains(sc.chPrev)) {
if (setWord.Contains(sc.chPrev) || sc.chPrev == '.') {
char s[100];
sc.GetCurrent(s, sizeof(s));
if (keywords.InList(s)) {

View File

@ -113,6 +113,10 @@ static bool HasPrevLineContent(StyleContext &sc) {
return false;
}
static bool AtTermStart(StyleContext &sc) {
return sc.currentPos == 0 || isspacechar(sc.chPrev);
}
static bool IsValidHrule(const unsigned int endPos, StyleContext &sc) {
int c, count = 1;
unsigned int i = 0;
@ -373,35 +377,38 @@ static void ColorizeMarkdownDoc(unsigned int startPos, int length, int initStyle
}
}
// Code - also a special case for alternate inside spacing
if (sc.Match("``") && sc.GetRelative(3) != ' ') {
if (sc.Match("``") && sc.GetRelative(3) != ' ' && AtTermStart(sc)) {
sc.SetState(SCE_MARKDOWN_CODE2);
sc.Forward();
}
else if (sc.ch == '`' && sc.chNext != ' ') {
else if (sc.ch == '`' && sc.chNext != ' ' && AtTermStart(sc)) {
sc.SetState(SCE_MARKDOWN_CODE);
}
// Strong
else if (sc.Match("**") && sc.GetRelative(2) != ' ') {
else if (sc.Match("**") && sc.GetRelative(2) != ' ' && AtTermStart(sc)) {
sc.SetState(SCE_MARKDOWN_STRONG1);
sc.Forward();
}
else if (sc.Match("__") && sc.GetRelative(2) != ' ') {
else if (sc.Match("__") && sc.GetRelative(2) != ' ' && AtTermStart(sc)) {
sc.SetState(SCE_MARKDOWN_STRONG2);
sc.Forward();
}
// Emphasis
else if (sc.ch == '*' && sc.chNext != ' ')
else if (sc.ch == '*' && sc.chNext != ' ' && AtTermStart(sc)) {
sc.SetState(SCE_MARKDOWN_EM1);
else if (sc.ch == '_' && sc.chNext != ' ')
}
else if (sc.ch == '_' && sc.chNext != ' ' && AtTermStart(sc)) {
sc.SetState(SCE_MARKDOWN_EM2);
}
// Strikeout
else if (sc.Match("~~") && sc.GetRelative(2) != ' ') {
else if (sc.Match("~~") && sc.GetRelative(2) != ' ' && AtTermStart(sc)) {
sc.SetState(SCE_MARKDOWN_STRIKEOUT);
sc.Forward();
}
// Beginning of line
else if (IsNewline(sc.ch))
else if (IsNewline(sc.ch)) {
sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
}
}
// Advance if not holding back the cursor for this iteration.
if (!freezeCursor)

View File

@ -106,12 +106,12 @@ static void ColouriseMatlabOctaveDoc(
transpose = true;
}
} else if (sc.state == SCE_MATLAB_STRING) {
if (sc.ch == '\\') {
if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
sc.Forward();
}
} else if (sc.ch == '\'') {
sc.ForwardSetState(SCE_MATLAB_DEFAULT);
if (sc.ch == '\'') {
if (sc.chNext == '\'') {
sc.Forward();
} else {
sc.ForwardSetState(SCE_MATLAB_DEFAULT);
}
}
} else if (sc.state == SCE_MATLAB_DOUBLEQUOTESTRING) {
if (sc.ch == '\\') {

View File

@ -58,7 +58,7 @@ static bool IsBOperator(char ch) {
// Tests for BATCH Separators
static bool IsBSeparator(char ch) {
return (ch == '\\') || (ch == '.') || (ch == ';') ||
(ch == '\"') || (ch == '\'') || (ch == '/') || (ch == ')');
(ch == '\"') || (ch == '\'') || (ch == '/');
}
static void ColouriseBatchLine(
@ -854,13 +854,17 @@ static void ColouriseMakeLine(
styler.ColourTo(endPos, SCE_MAKE_PREPROCESSOR);
return;
}
int varCount = 0;
while (i < lengthLine) {
if (lineBuffer[i] == '$' && lineBuffer[i + 1] == '(') {
styler.ColourTo(startLine + i - 1, state);
state = SCE_MAKE_IDENTIFIER;
varCount++;
} else if (state == SCE_MAKE_IDENTIFIER && lineBuffer[i] == ')') {
styler.ColourTo(startLine + i, state);
state = SCE_MAKE_DEFAULT;
if (--varCount == 0) {
styler.ColourTo(startLine + i, state);
state = SCE_MAKE_DEFAULT;
}
}
// skip identifier and target styling if this is a command line
@ -1158,21 +1162,71 @@ static void ColouriseErrorListDoc(unsigned int startPos, int length, int, WordLi
}
}
static int isSpecial(char s) {
return (s == '\\') || (s == ',') || (s == ';') || (s == '\'') || (s == ' ') ||
(s == '\"') || (s == '`') || (s == '^') || (s == '~');
static bool latexIsSpecial(int ch) {
return (ch == '#') || (ch == '$') || (ch == '%') || (ch == '&') || (ch == '_') ||
(ch == '{') || (ch == '}') || (ch == ' ');
}
static int isTag(int start, Accessor &styler) {
char s[6];
unsigned int i = 0, e = 1;
while (i < 5 && e) {
s[i] = styler[start + i];
static bool latexIsBlank(int ch) {
return (ch == ' ') || (ch == '\t');
}
static bool latexIsBlankAndNL(int ch) {
return (ch == ' ') || (ch == '\t') || (ch == '\r') || (ch == '\n');
}
static bool latexIsLetter(int ch) {
return isascii(ch) && isalpha(ch);
}
static bool latexIsTagValid(int &i, int l, Accessor &styler) {
while (i < l) {
if (styler.SafeGetCharAt(i) == '{') {
while (i < l) {
i++;
if (styler.SafeGetCharAt(i) == '}') {
return true;
} else if (!latexIsLetter(styler.SafeGetCharAt(i)) &&
styler.SafeGetCharAt(i)!='*') {
return false;
}
}
} else if (!latexIsBlank(styler.SafeGetCharAt(i))) {
return false;
}
i++;
e = (strchr("{ \t", styler[start + i]) == NULL);
}
return false;
}
static bool latexNextNotBlankIs(int i, int l, Accessor &styler, char needle) {
char ch;
while (i < l) {
ch = styler.SafeGetCharAt(i);
if (!latexIsBlankAndNL(ch) && ch != '*') {
if (ch == needle)
return true;
else
return false;
}
i++;
}
return false;
}
static bool latexLastWordIs(int start, Accessor &styler, const char *needle) {
unsigned int i = 0;
unsigned int l = static_cast<unsigned int>(strlen(needle));
int ini = start-l+1;
char s[32];
while (i < l && i < 32) {
s[i] = styler.SafeGetCharAt(ini + i);
i++;
}
s[i] = '\0';
return (strcmp(s, "begin") == 0) || (strcmp(s, "end") == 0);
return (strcmp(s, needle) == 0);
}
static void ColouriseLatexDoc(unsigned int startPos, int length, int initStyle,
@ -1181,39 +1235,51 @@ static void ColouriseLatexDoc(unsigned int startPos, int length, int initStyle,
styler.StartAt(startPos);
int state = initStyle;
char chNext = styler[startPos];
char chNext = styler.SafeGetCharAt(startPos);
styler.StartSegment(startPos);
int lengthDoc = startPos + length;
char chVerbatimDelim = '\0';
for (int i = startPos; i < lengthDoc; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
if (styler.IsLeadByte(ch)) {
chNext = styler.SafeGetCharAt(i + 2);
i++;
chNext = styler.SafeGetCharAt(i + 1);
continue;
}
switch (state) {
case SCE_L_DEFAULT :
switch (ch) {
case '\\' :
styler.ColourTo(i - 1, state);
if (isSpecial(styler[i + 1])) {
styler.ColourTo(i + 1, SCE_L_COMMAND);
i++;
chNext = styler.SafeGetCharAt(i + 1);
if (latexIsSpecial(chNext)) {
state = SCE_L_SPECIAL;
} else {
if (isTag(i + 1, styler))
state = SCE_L_TAG;
else
if (latexIsLetter(chNext)) {
state = SCE_L_COMMAND;
} else {
if (chNext == '(' || chNext == '[') {
styler.ColourTo(i-1, state);
styler.ColourTo(i+1, SCE_L_SHORTCMD);
state = SCE_L_MATH;
if (chNext == '[')
state = SCE_L_MATH2;
i++;
chNext = styler.SafeGetCharAt(i+1);
} else {
state = SCE_L_SHORTCMD;
}
}
}
break;
case '$' :
styler.ColourTo(i - 1, state);
state = SCE_L_MATH;
if (chNext == '$') {
state = SCE_L_MATH2;
i++;
chNext = styler.SafeGetCharAt(i + 1);
}
@ -1224,29 +1290,124 @@ static void ColouriseLatexDoc(unsigned int startPos, int length, int initStyle,
break;
}
break;
case SCE_L_ERROR:
styler.ColourTo(i-1, state);
state = SCE_L_DEFAULT;
break;
case SCE_L_SPECIAL:
case SCE_L_SHORTCMD:
styler.ColourTo(i, state);
state = SCE_L_DEFAULT;
break;
case SCE_L_COMMAND :
if (chNext == '[' || chNext == '{' || chNext == '}' ||
chNext == ' ' || chNext == '\r' || chNext == '\n') {
if (!latexIsLetter(chNext)) {
styler.ColourTo(i, state);
state = SCE_L_DEFAULT;
i++;
chNext = styler.SafeGetCharAt(i + 1);
if (latexNextNotBlankIs(i+1, lengthDoc, styler, '[' )) {
state = SCE_L_CMDOPT;
} else if (latexLastWordIs(i, styler, "\\begin")) {
state = SCE_L_TAG;
} else if (latexLastWordIs(i, styler, "\\end")) {
state = SCE_L_TAG2;
} else if (latexLastWordIs(i, styler, "\\verb") &&
chNext != '*' && chNext != ' ') {
chVerbatimDelim = chNext;
state = SCE_L_VERBATIM;
}
}
break;
case SCE_L_CMDOPT :
if (ch == ']') {
styler.ColourTo(i, state);
state = SCE_L_DEFAULT;
}
break;
case SCE_L_TAG :
if (ch == '}') {
if (latexIsTagValid(i, lengthDoc, styler)) {
styler.ColourTo(i, state);
state = SCE_L_DEFAULT;
if (latexLastWordIs(i, styler, "{verbatim}")) {
state = SCE_L_VERBATIM;
} else if (latexLastWordIs(i, styler, "{comment}")) {
state = SCE_L_COMMENT2;
} else if (latexLastWordIs(i, styler, "{math}")) {
state = SCE_L_MATH;
} else if (latexLastWordIs(i, styler, "{displaymath}")) {
state = SCE_L_MATH2;
} else if (latexLastWordIs(i, styler, "{equation}")) {
state = SCE_L_MATH2;
}
} else {
state = SCE_L_ERROR;
styler.ColourTo(i, state);
state = SCE_L_DEFAULT;
}
chNext = styler.SafeGetCharAt(i+1);
break;
case SCE_L_TAG2 :
if (latexIsTagValid(i, lengthDoc, styler)) {
styler.ColourTo(i, state);
state = SCE_L_DEFAULT;
} else {
state = SCE_L_ERROR;
}
chNext = styler.SafeGetCharAt(i+1);
break;
case SCE_L_MATH :
if (ch == '$') {
if (chNext == '$') {
i++;
chNext = styler.SafeGetCharAt(i + 1);
}
styler.ColourTo(i, state);
state = SCE_L_DEFAULT;
} else if (ch == '\\' && chNext == ')') {
styler.ColourTo(i-1, state);
styler.ColourTo(i+1, SCE_L_SHORTCMD);
i++;
chNext = styler.SafeGetCharAt(i+1);
state = SCE_L_DEFAULT;
} else if (ch == '\\') {
int match = i + 3;
if (latexLastWordIs(match, styler, "\\end")) {
match++;
if (latexIsTagValid(match, lengthDoc, styler)) {
if (latexLastWordIs(match, styler, "{math}")) {
styler.ColourTo(i-1, state);
state = SCE_L_COMMAND;
}
}
}
}
break;
case SCE_L_MATH2 :
if (ch == '$') {
if (chNext == '$') {
i++;
chNext = styler.SafeGetCharAt(i + 1);
styler.ColourTo(i, state);
state = SCE_L_DEFAULT;
} else {
styler.ColourTo(i, SCE_L_ERROR);
state = SCE_L_DEFAULT;
}
} else if (ch == '\\' && chNext == ']') {
styler.ColourTo(i-1, state);
styler.ColourTo(i+1, SCE_L_SHORTCMD);
i++;
chNext = styler.SafeGetCharAt(i+1);
state = SCE_L_DEFAULT;
} else if (ch == '\\') {
int match = i + 3;
if (latexLastWordIs(match, styler, "\\end")) {
match++;
if (latexIsTagValid(match, lengthDoc, styler)) {
if (latexLastWordIs(match, styler, "{displaymath}")) {
styler.ColourTo(i-1, state);
state = SCE_L_COMMAND;
} else if (latexLastWordIs(match, styler, "{equation}")) {
styler.ColourTo(i-1, state);
state = SCE_L_COMMAND;
}
}
}
}
break;
case SCE_L_COMMENT :
@ -1254,6 +1415,43 @@ static void ColouriseLatexDoc(unsigned int startPos, int length, int initStyle,
styler.ColourTo(i - 1, state);
state = SCE_L_DEFAULT;
}
break;
case SCE_L_COMMENT2 :
if (ch == '\\') {
int match = i + 3;
if (latexLastWordIs(match, styler, "\\end")) {
match++;
if (latexIsTagValid(match, lengthDoc, styler)) {
if (latexLastWordIs(match, styler, "{comment}")) {
styler.ColourTo(i-1, state);
state = SCE_L_COMMAND;
}
}
}
}
break;
case SCE_L_VERBATIM :
if (ch == '\\') {
int match = i + 3;
if (latexLastWordIs(match, styler, "\\end")) {
match++;
if (latexIsTagValid(match, lengthDoc, styler)) {
if (latexLastWordIs(match, styler, "{verbatim}")) {
styler.ColourTo(i-1, state);
state = SCE_L_COMMAND;
}
}
}
} else if (chNext == chVerbatimDelim) {
styler.ColourTo(i+1, state);
state = SCE_L_DEFAULT;
chVerbatimDelim = '\0';
} else if (chVerbatimDelim != '\0' && (ch == '\n' || ch == '\r')) {
styler.ColourTo(i, SCE_L_ERROR);
state = SCE_L_DEFAULT;
chVerbatimDelim = '\0';
}
break;
}
}
styler.ColourTo(lengthDoc-1, state);

File diff suppressed because it is too large Load Diff

View File

@ -28,7 +28,7 @@ using namespace Scintilla;
#endif
/* kwCDef, kwCTypeName only used for Cython */
enum kwType { kwOther, kwClass, kwDef, kwImport, kwCDef, kwCTypeName };
enum kwType { kwOther, kwClass, kwDef, kwImport, kwCDef, kwCTypeName, kwCPDef };
static const int indicatorWhitespace = 1;
@ -165,6 +165,11 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
// Set to 1 to allow strings to span newline characters.
bool stringsOverNewline = styler.GetPropertyInt("lexer.python.strings.over.newline") != 0;
// property lexer.python.keywords2.no.sub.identifiers
// When enabled, it will not style keywords2 items that are used as a sub-identifier.
// Example: when set, will not highlight "foo.open" when "open" is a keywords2 item.
const bool keywords2NoSubIdentifiers = styler.GetPropertyInt("lexer.python.keywords2.no.sub.identifiers") != 0;
initStyle = initStyle & 31;
if (initStyle == SCE_P_STRINGEOL) {
initStyle = SCE_P_DEFAULT;
@ -246,7 +251,7 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
style = SCE_P_CLASSNAME;
} else if (kwLast == kwDef) {
style = SCE_P_DEFNAME;
} else if (kwLast == kwCDef) {
} else if (kwLast == kwCDef || kwLast == kwCPDef) {
int pos = sc.currentPos;
unsigned char ch = styler.SafeGetCharAt(pos, '\0');
while (ch != '\0') {
@ -264,7 +269,16 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
}
}
} else if (keywords2.InList(s)) {
style = SCE_P_WORD2;
if (keywords2NoSubIdentifiers) {
// We don't want to highlight keywords2
// that are used as a sub-identifier,
// i.e. not open in "foo.open".
int pos = styler.GetStartSegment() - 1;
if (pos < 0 || (styler.SafeGetCharAt(pos, '\0') != '.'))
style = SCE_P_WORD2;
} else {
style = SCE_P_WORD2;
}
}
sc.ChangeState(style);
sc.SetState(SCE_P_DEFAULT);
@ -277,11 +291,13 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
kwLast = kwImport;
else if (0 == strcmp(s, "cdef"))
kwLast = kwCDef;
else if (0 == strcmp(s, "cpdef"))
kwLast = kwCPDef;
else if (0 == strcmp(s, "cimport"))
kwLast = kwImport;
else if (kwLast != kwCDef)
else if (kwLast != kwCDef && kwLast != kwCPDef)
kwLast = kwOther;
} else if (kwLast != kwCDef) {
} else if (kwLast != kwCDef && kwLast != kwCPDef) {
kwLast = kwOther;
}
}
@ -337,8 +353,8 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
indentGood = true;
}
// One cdef line, clear kwLast only at end of line
if (kwLast == kwCDef && sc.atLineEnd) {
// One cdef or cpdef line, clear kwLast only at end of line
if ((kwLast == kwCDef || kwLast == kwCPDef) && sc.atLineEnd) {
kwLast = kwOther;
}
@ -412,12 +428,8 @@ static bool IsQuoteLine(int line, Accessor &styler) {
static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unused*/,
WordList *[], Accessor &styler) {
const int maxPos = startPos + length;
const int maxLines = styler.GetLine(maxPos - 1); // Requested last line
const int docLines = styler.GetLine(styler.Length() - 1); // Available last line
// property fold.comment.python
// This option enables folding multi-line comments when using the Python lexer.
const bool foldComment = styler.GetPropertyInt("fold.comment.python") != 0;
const int maxLines = (maxPos == styler.Length()) ? styler.GetLine(maxPos) : styler.GetLine(maxPos - 1); // Requested last line
const int docLines = styler.GetLine(styler.Length()); // Available last line
// property fold.quotes.python
// This option enables folding multi-line quoted strings when using the Python lexer.
@ -448,14 +460,11 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse
if (lineCurrent >= 1)
prev_state = styler.StyleAt(startPos - 1) & 31;
int prevQuote = foldQuotes && ((prev_state == SCE_P_TRIPLE) || (prev_state == SCE_P_TRIPLEDOUBLE));
int prevComment = 0;
if (lineCurrent >= 1)
prevComment = foldComment && IsCommentLine(lineCurrent - 1, styler);
// Process all characters to end of requested range or end of any triple quote
// or comment that hangs over the end of the range. Cap processing in all cases
// to end of document (in case of unclosed quote or comment at end).
while ((lineCurrent <= docLines) && ((lineCurrent <= maxLines) || prevQuote || prevComment)) {
//that hangs over the end of the range. Cap processing in all cases
// to end of document (in case of unclosed quote at end).
while ((lineCurrent <= docLines) && ((lineCurrent <= maxLines) || prevQuote)) {
// Gather info
int lev = indentCurrent;
@ -465,16 +474,13 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse
if (lineNext <= docLines) {
// Information about next line is only available if not at end of document
indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL);
int style = styler.StyleAt(styler.LineStart(lineNext)) & 31;
int lookAtPos = (styler.LineStart(lineNext) == styler.Length()) ? styler.Length() - 1 : styler.LineStart(lineNext);
int style = styler.StyleAt(lookAtPos) & 31;
quote = foldQuotes && ((style == SCE_P_TRIPLE) || (style == SCE_P_TRIPLEDOUBLE));
}
const int quote_start = (quote && !prevQuote);
const int quote_continue = (quote && prevQuote);
const int comment = foldComment && IsCommentLine(lineCurrent, styler);
const int comment_start = (comment && !prevComment && (lineNext <= docLines) &&
IsCommentLine(lineNext, styler) && (lev > SC_FOLDLEVELBASE));
const int comment_continue = (comment && prevComment);
if ((!quote || !prevQuote) && !comment)
if (!quote || !prevQuote)
indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;
if (quote)
indentNext = indentCurrentLevel;
@ -487,12 +493,6 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse
} else if (quote_continue || prevQuote) {
// Add level to rest of lines in the string
lev = lev + 1;
} else if (comment_start) {
// Place fold point at start of a block of comments
lev |= SC_FOLDLEVELHEADERFLAG;
} else if (comment_continue) {
// Add level to rest of lines in the block
lev = lev + 1;
}
// Skip past any blank lines for next indent level info; we skip also
@ -540,18 +540,17 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse
}
}
// Set fold header on non-quote/non-comment line
if (!quote && !comment && !(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
// Set fold header on non-quote line
if (!quote && !(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK))
lev |= SC_FOLDLEVELHEADERFLAG;
}
// Keep track of triple quote and block comment state of previous line
// Keep track of triple quote state of previous line
prevQuote = quote;
prevComment = comment_start || comment_continue;
// Set fold level for this line and move to next line
styler.SetLevel(lineCurrent, lev);
styler.SetLevel(lineCurrent, foldCompact ? lev : lev & ~SC_FOLDLEVELWHITEFLAG);
indentCurrent = indentNext;
lineCurrent = lineNext;
}

View File

@ -16,7 +16,6 @@
#include "Scintilla.h"
#include "SciLexer.h"
#include "PropSetSimple.h"
#include "WordList.h"
#include "LexAccessor.h"
#include "Accessor.h"
@ -1729,7 +1728,13 @@ static void FoldRbDoc(unsigned int startPos, int length, int initStyle,
) {
levelCurrent++;
}
}
} else if (style == SCE_RB_HERE_DELIM) {
if (styler.SafeGetCharAt(i-2) == '<' && styler.SafeGetCharAt(i-1) == '<') {
levelCurrent++;
} else if (styleNext == SCE_RB_DEFAULT) {
levelCurrent--;
}
}
if (atEOL) {
int lev = levelPrev;
if (visibleChars == 0 && foldCompact)
@ -1765,4 +1770,4 @@ static const char * const rubyWordListDesc[] = {
0
};
LexerModule lmRuby(SCLEX_RUBY, ColouriseRbDoc, "ruby", FoldRbDoc, rubyWordListDesc);
LexerModule lmRuby(SCLEX_RUBY, ColouriseRbDoc, "ruby", FoldRbDoc, rubyWordListDesc, 6);

View File

@ -204,8 +204,8 @@ struct OptionSetSQL : public OptionSet<OptionsSQL> {
OptionSetSQL() {
DefineProperty("fold", &OptionsSQL::fold);
DefineProperty("lexer.sql.fold.at.else", &OptionsSQL::foldAtElse,
"This option enables SQL folding on a \"ELSE\" and \"ELSIF\"line of an IF statement.");
DefineProperty("fold.sql.at.else", &OptionsSQL::foldAtElse,
"This option enables SQL folding on a \"ELSE\" and \"ELSIF\" line of an IF statement.");
DefineProperty("fold.comment", &OptionsSQL::foldComment);
@ -283,6 +283,20 @@ private:
style == SCE_SQL_COMMENTDOCKEYWORDERROR;
}
bool IsCommentStyle (int style) {
switch (style) {
case SCE_SQL_COMMENT :
case SCE_SQL_COMMENTDOC :
case SCE_SQL_COMMENTLINE :
case SCE_SQL_COMMENTLINEDOC :
case SCE_SQL_COMMENTDOCKEYWORD :
case SCE_SQL_COMMENTDOCKEYWORDERROR :
return true;
default :
return false;
}
}
OptionsSQL options;
OptionSetSQL osSQL;
SQLStates sqlStates;
@ -521,7 +535,7 @@ void SCI_METHOD LexerSQL::Fold(unsigned int startPos, int length, int initStyle,
style = styleNext;
styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
if (atEOL || (ch == ';')) {
if (atEOL || (!IsCommentStyle(style) && ch == ';')) {
if (endFound) {
//Maybe this is the end of "EXCEPTION" BLOCK (eg. "BEGIN ... EXCEPTION ... END;")
sqlStatesCurrentLine = sqlStates.IntoExceptionBlock(sqlStatesCurrentLine, false);
@ -554,7 +568,7 @@ void SCI_METHOD LexerSQL::Fold(unsigned int startPos, int length, int initStyle,
if (ch == '(') {
if (levelCurrent > levelNext)
levelCurrent--;
levelNext++;
levelNext++;
} else if (ch == ')') {
levelNext--;
} else if ((!options.foldOnlyBegin) && ch == ';') {

View File

@ -235,7 +235,7 @@ static void FoldNoBoxVHDLDoc(
}
}
}
for(j=j+strlen(prevWord); j<endPos; j++)
for(j=j+static_cast<unsigned int>(strlen(prevWord)); j<endPos; j++)
{
char ch = styler.SafeGetCharAt(j);
int style = styler.StyleAt(j);

View File

@ -29,7 +29,7 @@ using namespace Scintilla;
#endif
static inline bool IsAWordChar(const int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '\'');
return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '\''|| ch == '$');
}
static inline bool IsAWordStart(const int ch) {
@ -269,24 +269,36 @@ static void FoldNoBoxVerilogDoc(unsigned int startPos, int length, int initStyle
if (styler.Match(j, "case") ||
styler.Match(j, "casex") ||
styler.Match(j, "casez") ||
styler.Match(j, "class") ||
styler.Match(j, "function") ||
styler.Match(j, "fork") ||
styler.Match(j, "generate") ||
styler.Match(j, "covergroup") ||
styler.Match(j, "package") ||
styler.Match(j, "primitive") ||
styler.Match(j, "program") ||
styler.Match(j, "sequence") ||
styler.Match(j, "specify") ||
styler.Match(j, "table") ||
styler.Match(j, "task") ||
styler.Match(j, "generate") ||
styler.Match(j, "specify") ||
styler.Match(j, "primitive") ||
styler.Match(j, "fork") ||
(styler.Match(j, "module") && foldAtModule) ||
styler.Match(j, "begin")) {
levelNext++;
} else if (styler.Match(j, "endcase") ||
styler.Match(j, "endclass") ||
styler.Match(j, "endfunction") ||
styler.Match(j, "join") ||
styler.Match(j, "endtask") ||
styler.Match(j, "endgenerate") ||
styler.Match(j, "endtable") ||
styler.Match(j, "endspecify") ||
styler.Match(j, "endgroup") ||
styler.Match(j, "endpackage") ||
styler.Match(j, "endprimitive") ||
styler.Match(j, "endprogram") ||
styler.Match(j, "endsequence") ||
styler.Match(j, "endspecify") ||
styler.Match(j, "endtable") ||
styler.Match(j, "endtask") ||
styler.Match(j, "join") ||
styler.Match(j, "join_any") ||
styler.Match(j, "join_none") ||
(styler.Match(j, "endmodule") && foldAtModule) ||
(styler.Match(j, "end") && !IsAWordChar(styler.SafeGetCharAt(j+3)))) {
levelNext--;

View File

@ -71,7 +71,7 @@ int Accessor::IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsComment
*flags = spaceFlags;
indent += SC_FOLDLEVELBASE;
// if completely empty line or the start of a comment...
if ((ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') ||
if ((LineStart(line) == Length()) || (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') ||
(pfnIsCommentLeader && (*pfnIsCommentLeader)(*this, pos, end-pos)))
return indent | SC_FOLDLEVELWHITEFLAG;
else

View File

@ -119,7 +119,6 @@ inline bool iswordstart(int ch) {
inline bool isoperator(int ch) {
if (IsASCII(ch) && IsAlphaNumeric(ch))
return false;
// '.' left out as it is used to make up numbers
if (ch == '%' || ch == '^' || ch == '&' || ch == '*' ||
ch == '(' || ch == ')' || ch == '-' || ch == '+' ||
ch == '=' || ch == '|' || ch == '{' || ch == '}' ||

View File

@ -61,9 +61,10 @@ void PropSetSimple::Set(const char *keyVal) {
endVal++;
const char *eqAt = strchr(keyVal, '=');
if (eqAt) {
Set(keyVal, eqAt + 1, eqAt-keyVal, endVal - eqAt - 1);
Set(keyVal, eqAt + 1, static_cast<int>(eqAt-keyVal),
static_cast<int>(endVal - eqAt - 1));
} else if (*keyVal) { // No '=' so assume '=1'
Set(keyVal, "1", endVal-keyVal, 1);
Set(keyVal, "1", static_cast<int>(endVal-keyVal), 1);
}
}
@ -150,7 +151,7 @@ char *PropSetSimple::Expanded(const char *key) const {
int PropSetSimple::GetExpanded(const char *key, char *result) const {
char *val = Expanded(key);
const int n = strlen(val);
const int n = static_cast<int>(strlen(val));
if (result) {
strcpy(result, val);
}

View File

@ -43,12 +43,12 @@ public:
}
void Set(int position, T value) {
Delete(position);
if ((states.size() == 0) || (value != states[states.size()-1].value)) {
if (states.empty() || (value != states[states.size()-1].value)) {
states.push_back(State(position, value));
}
}
T ValueAt(int position) {
if (!states.size())
if (states.empty())
return T();
if (position < states[0].position)
return T();
@ -92,7 +92,7 @@ public:
changed = true;
}
typename stateVector::const_iterator startOther = other.states.begin();
if (!states.empty() && states.back().value == startOther->value)
if (!states.empty() && !other.states.empty() && states.back().value == startOther->value)
++startOther;
if (startOther != other.states.end()) {
states.insert(states.end(), startOther, other.states.end());

View File

@ -55,7 +55,6 @@ public:
styler(styler_),
endPos(startPos + length),
currentPos(startPos),
atLineStart(true),
atLineEnd(false),
state(initStyle & chMask), // Mask off all bits which aren't in the chMask.
chPrev(0),
@ -63,6 +62,7 @@ public:
chNext(0) {
styler.StartAt(startPos, chMask);
styler.StartSegment(startPos);
atLineStart = static_cast<unsigned int>(styler.LineStart(styler.GetLine(startPos))) == startPos;
unsigned int pos = currentPos;
ch = static_cast<unsigned char>(styler.SafeGetCharAt(pos));
if (styler.IsLeadByte(static_cast<char>(ch))) {

View File

@ -11,6 +11,8 @@
#include <stdio.h>
#include <stdarg.h>
#include <algorithm>
#include "WordList.h"
#ifdef SCI_NAMESPACE
@ -86,22 +88,34 @@ void WordList::Clear() {
len = 0;
}
extern "C" int cmpString(const void *a1, const void *a2) {
// Can't work out the correct incantation to use modern casts here
return strcmp(*(char **)(a1), *(char **)(a2));
#ifdef _MSC_VER
static bool cmpWords(const char *a, const char *b) {
return strcmp(a, b) == -1;
}
#else
static int cmpWords(const void *a, const void *b) {
return strcmp(*static_cast<const char * const *>(a), *static_cast<const char * const *>(b));
}
static void SortWordList(char **words, unsigned int len) {
qsort(reinterpret_cast<void *>(words), len, sizeof(*words),
cmpString);
qsort(reinterpret_cast<void *>(words), len, sizeof(*words), cmpWords);
}
#endif
void WordList::Set(const char *s) {
Clear();
list = new char[strlen(s) + 1];
strcpy(list, s);
words = ArrayFromWordList(list, &len, onlyLineEnds);
#ifdef _MSC_VER
std::sort(words, words + len, cmpWords);
#else
SortWordList(words, len);
#endif
for (unsigned int k = 0; k < (sizeof(starts) / sizeof(starts[0])); k++)
starts[k] = -1;
for (int l = len - 1; l >= 0; l--) {
@ -121,7 +135,7 @@ bool WordList::InList(const char *s) const {
unsigned char firstChar = s[0];
int j = starts[firstChar];
if (j >= 0) {
while ((unsigned char)words[j][0] == firstChar) {
while (static_cast<unsigned char>(words[j][0]) == firstChar) {
if (s[1] == words[j][1]) {
const char *a = words[j] + 1;
const char *b = s + 1;
@ -163,7 +177,7 @@ bool WordList::InListAbbreviated(const char *s, const char marker) const {
unsigned char firstChar = s[0];
int j = starts[firstChar];
if (j >= 0) {
while (words[j][0] == firstChar) {
while (static_cast<unsigned char>(words[j][0]) == firstChar) {
bool isSubword = false;
int start = 1;
if (words[j][1] == marker) {

View File

@ -1,4 +1,4 @@
A patch to Scintilla 2.25 containing our changes to Scintilla
A patch to Scintilla 2.29 containing our changes to Scintilla
(removing unused lexers and an updated marshallers file).
diff -Naur scintilla_orig/gtk/scintilla-marshal.c scintilla/gtk/scintilla-marshal.c
--- scintilla_orig/gtk/scintilla-marshal.c 2010-10-27 23:15:45.000000000 +0200

View File

@ -100,7 +100,7 @@ void CallTip::DrawChunk(Surface *surface, int &x, const char *s,
int ends[numEnds + 2];
for (int i=0; i<len; i++) {
if ((maxEnd < numEnds) &&
(IsArrowCharacter(s[i]) || IsTabCharacter(s[i])) ) {
(IsArrowCharacter(s[i]) || IsTabCharacter(s[i]))) {
if (i > 0)
ends[maxEnd++] = i;
ends[maxEnd++] = i+1;

View File

@ -168,6 +168,14 @@ bool ContractionState::SetVisible(int lineDocStart, int lineDocEnd, bool visible
}
}
bool ContractionState::HiddenLines() const {
if (OneToOne()) {
return false;
} else {
return !visible->AllSameAs(1);
}
}
bool ContractionState::GetExpanded(int lineDoc) const {
if (OneToOne()) {
return true;
@ -223,7 +231,7 @@ int ContractionState::GetHeight(int lineDoc) const {
bool ContractionState::SetHeight(int lineDoc, int height) {
if (OneToOne() && (height == 1)) {
return false;
} else {
} else if (lineDoc < LinesInDoc()) {
EnsureData();
if (GetHeight(lineDoc) != height) {
if (GetVisible(lineDoc)) {
@ -236,6 +244,8 @@ bool ContractionState::SetHeight(int lineDoc, int height) {
Check();
return false;
}
} else {
return false;
}
}

View File

@ -48,6 +48,7 @@ public:
bool GetVisible(int lineDoc) const;
bool SetVisible(int lineDocStart, int lineDocEnd, bool visible);
bool HiddenLines() const;
bool GetExpanded(int lineDoc) const;
bool SetExpanded(int lineDoc, bool expanded);

View File

@ -28,7 +28,7 @@ Decoration::~Decoration() {
}
bool Decoration::Empty() {
return rs.starts->Partitions() == 1;
return rs.Runs() == 1;
}
DecorationList::DecorationList() : currentIndicator(0), currentValue(1), current(0),
@ -126,9 +126,13 @@ bool DecorationList::FillRange(int &position, int value, int &fillLength) {
}
void DecorationList::InsertSpace(int position, int insertLength) {
const bool atEnd = position == lengthDocument;
lengthDocument += insertLength;
for (Decoration *deco=root; deco; deco = deco->next) {
deco->rs.InsertSpace(position, insertLength);
if (atEnd) {
deco->rs.FillRange(position, 0, insertLength);
}
}
}

View File

@ -2,7 +2,7 @@
/** @file Document.cxx
** Text document that handles notifications, DBCS, styling, words and end of line.
**/
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
@ -87,10 +87,10 @@ void LexInterface::Colourise(int start, int end) {
Document::Document() {
refCount = 0;
#ifdef __unix__
eolMode = SC_EOL_LF;
#else
#ifdef _WIN32
eolMode = SC_EOL_CRLF;
#else
eolMode = SC_EOL_LF;
#endif
dbcsCodePage = 0;
stylingBits = 5;
@ -316,15 +316,18 @@ static bool IsSubordinate(int levelStart, int levelTry) {
return (levelStart & SC_FOLDLEVELNUMBERMASK) < (levelTry & SC_FOLDLEVELNUMBERMASK);
}
int Document::GetLastChild(int lineParent, int level) {
int Document::GetLastChild(int lineParent, int level, int lastLine) {
if (level == -1)
level = GetLevel(lineParent) & SC_FOLDLEVELNUMBERMASK;
int maxLine = LinesTotal();
int lookLastLine = (lastLine != -1) ? Platform::Minimum(LinesTotal() - 1, lastLine) : -1;
int lineMaxSubord = lineParent;
while (lineMaxSubord < maxLine - 1) {
EnsureStyledTo(LineStart(lineMaxSubord + 2));
if (!IsSubordinate(level, GetLevel(lineMaxSubord + 1)))
break;
if ((lookLastLine != -1) && (lineMaxSubord >= lookLastLine) && !(GetLevel(lineMaxSubord) & SC_FOLDLEVELWHITEFLAG))
break;
lineMaxSubord++;
}
if (lineMaxSubord > lineParent) {
@ -355,6 +358,76 @@ int Document::GetFoldParent(int line) {
}
}
void Document::GetHighlightDelimiters(HighlightDelimiter &highlightDelimiter, int line, int lastLine) {
int level = GetLevel(line);
int lookLastLine = Platform::Maximum(line, lastLine) + 1;
int lookLine = line;
int lookLineLevel = level;
int lookLineLevelNum = lookLineLevel & SC_FOLDLEVELNUMBERMASK;
while ((lookLine > 0) && ((lookLineLevel & SC_FOLDLEVELWHITEFLAG) ||
((lookLineLevel & SC_FOLDLEVELHEADERFLAG) && (lookLineLevelNum >= (GetLevel(lookLine + 1) & SC_FOLDLEVELNUMBERMASK))))) {
lookLineLevel = GetLevel(--lookLine);
lookLineLevelNum = lookLineLevel & SC_FOLDLEVELNUMBERMASK;
}
int beginFoldBlock = (lookLineLevel & SC_FOLDLEVELHEADERFLAG) ? lookLine : GetFoldParent(lookLine);
if (beginFoldBlock == -1) {
highlightDelimiter.Clear();
return;
}
int endFoldBlock = GetLastChild(beginFoldBlock, -1, lookLastLine);
int firstChangeableLineBefore = -1;
if (endFoldBlock < line) {
lookLine = beginFoldBlock - 1;
lookLineLevel = GetLevel(lookLine);
lookLineLevelNum = lookLineLevel & SC_FOLDLEVELNUMBERMASK;
while ((lookLine >= 0) && (lookLineLevelNum >= SC_FOLDLEVELBASE)) {
if (lookLineLevel & SC_FOLDLEVELHEADERFLAG) {
if (GetLastChild(lookLine, -1, lookLastLine) == line) {
beginFoldBlock = lookLine;
endFoldBlock = line;
firstChangeableLineBefore = line - 1;
}
}
if ((lookLine > 0) && (lookLineLevelNum == SC_FOLDLEVELBASE) && ((GetLevel(lookLine - 1) & SC_FOLDLEVELNUMBERMASK) > lookLineLevelNum))
break;
lookLineLevel = GetLevel(--lookLine);
lookLineLevelNum = lookLineLevel & SC_FOLDLEVELNUMBERMASK;
}
}
if (firstChangeableLineBefore == -1) {
for (lookLine = line - 1, lookLineLevel = GetLevel(lookLine), lookLineLevelNum = lookLineLevel & SC_FOLDLEVELNUMBERMASK;
lookLine >= beginFoldBlock;
lookLineLevel = GetLevel(--lookLine), lookLineLevelNum = lookLineLevel & SC_FOLDLEVELNUMBERMASK) {
if ((lookLineLevel & SC_FOLDLEVELWHITEFLAG) || (lookLineLevelNum > (level & SC_FOLDLEVELNUMBERMASK))) {
firstChangeableLineBefore = lookLine;
break;
}
}
}
if (firstChangeableLineBefore == -1)
firstChangeableLineBefore = beginFoldBlock - 1;
int firstChangeableLineAfter = -1;
for (lookLine = line + 1, lookLineLevel = GetLevel(lookLine), lookLineLevelNum = lookLineLevel & SC_FOLDLEVELNUMBERMASK;
lookLine <= endFoldBlock;
lookLineLevel = GetLevel(++lookLine), lookLineLevelNum = lookLineLevel & SC_FOLDLEVELNUMBERMASK) {
if ((lookLineLevel & SC_FOLDLEVELHEADERFLAG) && (lookLineLevelNum < (GetLevel(lookLine + 1) & SC_FOLDLEVELNUMBERMASK))) {
firstChangeableLineAfter = lookLine;
break;
}
}
if (firstChangeableLineAfter == -1)
firstChangeableLineAfter = endFoldBlock + 1;
highlightDelimiter.beginFoldBlock = beginFoldBlock;
highlightDelimiter.endFoldBlock = endFoldBlock;
highlightDelimiter.firstChangeableLineBefore = firstChangeableLineBefore;
highlightDelimiter.firstChangeableLineAfter = firstChangeableLineAfter;
}
int Document::ClampPositionIntoDocument(int pos) {
return Platform::Clamp(pos, 0, Length());
}
@ -589,7 +662,8 @@ bool SCI_METHOD Document::IsDBCSLeadByte(char ch) const {
case 932:
// Shift_jis
return ((uch >= 0x81) && (uch <= 0x9F)) ||
((uch >= 0xE0) && (uch <= 0xEF));
((uch >= 0xE0) && (uch <= 0xFC));
// Lead bytes F0 to FC may be a Microsoft addition.
case 936:
// GBK
return (uch >= 0x81) && (uch <= 0xFE);
@ -609,6 +683,55 @@ bool SCI_METHOD Document::IsDBCSLeadByte(char ch) const {
return false;
}
inline bool IsSpaceOrTab(int ch) {
return ch == ' ' || ch == '\t';
}
// Need to break text into segments near lengthSegment but taking into
// account the encoding to not break inside a UTF-8 or DBCS character
// and also trying to avoid breaking inside a pair of combining characters.
// The segment length must always be long enough (more than 4 bytes)
// so that there will be at least one whole character to make a segment.
// For UTF-8, text must consist only of valid whole characters.
// In preference order from best to worst:
// 1) Break after space
// 2) Break before punctuation
// 3) Break after whole character
int Document::SafeSegment(const char *text, int length, int lengthSegment) {
if (length <= lengthSegment)
return length;
int lastSpaceBreak = -1;
int lastPunctuationBreak = -1;
int lastEncodingAllowedBreak = -1;
for (int j=0; j < lengthSegment;) {
unsigned char ch = static_cast<unsigned char>(text[j]);
if (j > 0) {
if (IsSpaceOrTab(text[j - 1]) && !IsSpaceOrTab(text[j])) {
lastSpaceBreak = j;
}
if (ch < 'A') {
lastPunctuationBreak = j;
}
}
lastEncodingAllowedBreak = j;
if (dbcsCodePage == SC_CP_UTF8) {
j += (ch < 0x80) ? 1 : BytesFromLead(ch);
} else if (dbcsCodePage) {
j += IsDBCSLeadByte(ch) ? 2 : 1;
} else {
j++;
}
}
if (lastSpaceBreak >= 0) {
return lastSpaceBreak;
} else if (lastPunctuationBreak >= 0) {
return lastPunctuationBreak;
}
return lastEncodingAllowedBreak;
}
void Document::ModifiedAt(int pos) {
if (endStyled > pos)
endStyled = pos;
@ -833,7 +956,7 @@ bool Document::InsertChar(int pos, char ch) {
* Insert a null terminated string.
*/
bool Document::InsertCString(int position, const char *s) {
return InsertString(position, s, strlen(s));
return InsertString(position, s, static_cast<int>(strlen(s)));
}
void Document::ChangeChar(int pos, char ch) {
@ -990,17 +1113,17 @@ void Document::Indent(bool forwards, int lineBottom, int lineTop) {
// Convert line endings for a piece of text to a particular mode.
// Stop at len or when a NUL is found.
// Caller must delete the returned pointer.
char *Document::TransformLineEnds(int *pLenOut, const char *s, size_t len, int eolMode) {
char *Document::TransformLineEnds(int *pLenOut, const char *s, size_t len, int eolModeWanted) {
char *dest = new char[2 * len + 1];
const char *sptr = s;
char *dptr = dest;
for (size_t i = 0; (i < len) && (*sptr != '\0'); i++) {
if (*sptr == '\n' || *sptr == '\r') {
if (eolMode == SC_EOL_CR) {
if (eolModeWanted == SC_EOL_CR) {
*dptr++ = '\r';
} else if (eolMode == SC_EOL_LF) {
} else if (eolModeWanted == SC_EOL_LF) {
*dptr++ = '\n';
} else { // eolMode == SC_EOL_CRLF
} else { // eolModeWanted == SC_EOL_CRLF
*dptr++ = '\r';
*dptr++ = '\n';
}
@ -1232,7 +1355,7 @@ size_t Document::ExtractChar(int pos, char *bytes) {
size_t widthChar = UTF8CharLength(ch);
bytes[0] = ch;
for (size_t i=1; i<widthChar; i++) {
bytes[i] = cb.CharAt(pos+i);
bytes[i] = cb.CharAt(static_cast<int>(pos+i));
if (!GoodTrailByte(static_cast<unsigned char>(bytes[i]))) { // Bad byte
widthChar = 1;
}
@ -1305,7 +1428,6 @@ long Document::FindText(int minPos, int maxPos, const char *search,
// Compute actual search ranges needed
const int lengthFind = (*length == -1) ? static_cast<int>(strlen(search)) : *length;
const int endSearch = (startPos <= endPos) ? endPos - lengthFind + 1 : endPos;
//Platform::DebugPrintf("Find %d %d %s %d\n", startPos, endPos, ft->lpstrText, lengthFind);
const int limitPos = Platform::Maximum(startPos, endPos);
@ -1315,6 +1437,7 @@ long Document::FindText(int minPos, int maxPos, const char *search,
pos = NextPosition(pos, increment);
}
if (caseSensitive) {
const int endSearch = (startPos <= endPos) ? endPos - lengthFind + 1 : endPos;
while (forward ? (pos < endSearch) : (pos >= endSearch)) {
bool found = (pos + lengthFind) <= limitPos;
for (int indexSearch = 0; (indexSearch < lengthFind) && found; indexSearch++) {
@ -1330,8 +1453,9 @@ long Document::FindText(int minPos, int maxPos, const char *search,
const size_t maxBytesCharacter = 4;
const size_t maxFoldingExpansion = 4;
std::vector<char> searchThing(lengthFind * maxBytesCharacter * maxFoldingExpansion + 1);
const int lenSearch = pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind);
while (forward ? (pos < endSearch) : (pos >= endSearch)) {
const int lenSearch = static_cast<int>(
pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind));
while (forward ? (pos < endPos) : (pos >= endPos)) {
int widthFirstCharacter = 0;
int indexDocument = 0;
int indexSearch = 0;
@ -1341,11 +1465,13 @@ long Document::FindText(int minPos, int maxPos, const char *search,
(indexSearch < lenSearch)) {
char bytes[maxBytesCharacter + 1];
bytes[maxBytesCharacter] = 0;
const int widthChar = ExtractChar(pos + indexDocument, bytes);
const int widthChar = static_cast<int>(ExtractChar(pos + indexDocument, bytes));
if (!widthFirstCharacter)
widthFirstCharacter = widthChar;
if ((pos + indexDocument + widthChar) > limitPos)
break;
char folded[maxBytesCharacter * maxFoldingExpansion + 1];
const int lenFlat = pcf->Fold(folded, sizeof(folded), bytes, widthChar);
const int lenFlat = static_cast<int>(pcf->Fold(folded, sizeof(folded), bytes, widthChar));
folded[lenFlat] = 0;
// Does folded match the buffer
characterMatches = 0 == memcmp(folded, &searchThing[0] + indexSearch, lenFlat);
@ -1369,8 +1495,9 @@ long Document::FindText(int minPos, int maxPos, const char *search,
const size_t maxBytesCharacter = 2;
const size_t maxFoldingExpansion = 4;
std::vector<char> searchThing(lengthFind * maxBytesCharacter * maxFoldingExpansion + 1);
const int lenSearch = pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind);
while (forward ? (pos < endSearch) : (pos >= endSearch)) {
const int lenSearch = static_cast<int>(
pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind));
while (forward ? (pos < endPos) : (pos >= endPos)) {
int indexDocument = 0;
int indexSearch = 0;
bool characterMatches = true;
@ -1382,8 +1509,10 @@ long Document::FindText(int minPos, int maxPos, const char *search,
const int widthChar = IsDBCSLeadByte(bytes[0]) ? 2 : 1;
if (widthChar == 2)
bytes[1] = cb.CharAt(pos + indexDocument + 1);
if ((pos + indexDocument + widthChar) > limitPos)
break;
char folded[maxBytesCharacter * maxFoldingExpansion + 1];
const int lenFlat = pcf->Fold(folded, sizeof(folded), bytes, widthChar);
const int lenFlat = static_cast<int>(pcf->Fold(folded, sizeof(folded), bytes, widthChar));
folded[lenFlat] = 0;
// Does folded match the buffer
characterMatches = 0 == memcmp(folded, &searchThing[0] + indexSearch, lenFlat);
@ -1400,7 +1529,7 @@ long Document::FindText(int minPos, int maxPos, const char *search,
break;
}
} else {
CaseFolderTable caseFolder;
const int endSearch = (startPos <= endPos) ? endPos - lengthFind + 1 : endPos;
std::vector<char> searchThing(lengthFind + 1);
pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind);
while (forward ? (pos < endSearch) : (pos >= endSearch)) {
@ -1950,10 +2079,17 @@ long BuiltinRegex::FindText(Document *doc, int minPos, int maxPos, const char *s
// the start position is at end of line or between line end characters.
lineRangeStart++;
startPos = doc->LineStart(lineRangeStart);
} else if ((increment == -1) &&
(startPos <= doc->LineStart(lineRangeStart)) &&
(lineRangeStart > lineRangeEnd)) {
// the start position is at beginning of line.
lineRangeStart--;
startPos = doc->LineEnd(lineRangeStart);
}
int pos = -1;
int lenRet = 0;
char searchEnd = s[*length - 1];
char searchEndPrev = (*length > 1) ? s[*length - 2] : '\0';
int lineRangeBreak = lineRangeEnd + increment;
for (int line = lineRangeStart; line != lineRangeBreak; line += increment) {
int startOfLine = doc->LineStart(line);
@ -1965,7 +2101,7 @@ long BuiltinRegex::FindText(Document *doc, int minPos, int maxPos, const char *s
startOfLine = startPos;
}
if (line == lineRangeEnd) {
if ((endPos != endOfLine) && (searchEnd == '$'))
if ((endPos != endOfLine) && (searchEnd == '$') && (searchEndPrev != '\\'))
continue; // Can't match end of line if end position before end of line
endOfLine = endPos;
}
@ -1976,7 +2112,7 @@ long BuiltinRegex::FindText(Document *doc, int minPos, int maxPos, const char *s
startOfLine = endPos;
}
if (line == lineRangeStart) {
if ((startPos != endOfLine) && (searchEnd == '$'))
if ((startPos != endOfLine) && (searchEnd == '$') && (searchEndPrev != '\\'))
continue; // Can't match end of line if start position before end of line
endOfLine = startPos;
}
@ -1987,7 +2123,8 @@ long BuiltinRegex::FindText(Document *doc, int minPos, int maxPos, const char *s
if (success) {
pos = search.bopat[0];
lenRet = search.eopat[0] - search.bopat[0];
if (increment == -1) {
// There can be only one start of a line, so no need to look for last match in line
if ((increment == -1) && (s[0] != '^')) {
// Check for the last match on this line.
int repetitions = 1000; // Break out of infinite loop
while (success && (search.eopat[0] <= endOfLine) && (repetitions--)) {

View File

@ -2,7 +2,7 @@
/** @file Document.h
** Text document that handles notifications, DBCS, styling, words and end of line.
**/
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef DOCUMENT_H
@ -115,6 +115,46 @@ struct StyledText {
}
};
class HighlightDelimiter {
public:
HighlightDelimiter() : isEnabled(false) {
Clear();
}
void Clear() {
beginFoldBlock = -1;
endFoldBlock = -1;
firstChangeableLineBefore = -1;
firstChangeableLineAfter = -1;
}
bool NeedsDrawing(int line) {
return isEnabled && (line <= firstChangeableLineBefore || line >= firstChangeableLineAfter);
}
bool IsFoldBlockHighlighted(int line) {
return isEnabled && beginFoldBlock != -1 && beginFoldBlock <= line && line <= endFoldBlock;
}
bool IsHeadOfFoldBlock(int line) {
return beginFoldBlock == line && line < endFoldBlock;
}
bool IsBodyOfFoldBlock(int line) {
return beginFoldBlock != -1 && beginFoldBlock < line && line < endFoldBlock;
}
bool IsTailOfFoldBlock(int line) {
return beginFoldBlock != -1 && beginFoldBlock < line && line == endFoldBlock;
}
int beginFoldBlock; // Begin of current fold block
int endFoldBlock; // End of current fold block
int firstChangeableLineBefore; // First line that triggers repaint before starting line that determined current fold block
int firstChangeableLineAfter; // First line that triggers repaint after starting line that determined current fold block
bool isEnabled;
};
class CaseFolder {
public:
virtual ~CaseFolder() {
@ -234,6 +274,7 @@ public:
bool NextCharacter(int &pos, int moveDir); // Returns true if pos changed
int SCI_METHOD CodePage() const;
bool SCI_METHOD IsDBCSLeadByte(char ch) const;
int SafeSegment(const char *text, int length, int lengthSegment);
// Gateways to modifying document
void ModifiedAt(int pos);
@ -262,7 +303,7 @@ public:
int GetColumn(int position);
int FindColumn(int line, int column);
void Indent(bool forwards, int lineBottom, int lineTop);
static char *TransformLineEnds(int *pLenOut, const char *s, size_t len, int eolMode);
static char *TransformLineEnds(int *pLenOut, const char *s, size_t len, int eolModeWanted);
void ConvertLineEnds(int eolModeSet);
void SetReadOnly(bool set) { cb.SetReadOnly(set); }
bool IsReadOnly() { return cb.IsReadOnly(); }
@ -297,8 +338,9 @@ public:
int SCI_METHOD SetLevel(int line, int level);
int SCI_METHOD GetLevel(int line) const;
void ClearLevels();
int GetLastChild(int lineParent, int level=-1);
int GetLastChild(int lineParent, int level=-1, int lastLine=-1);
int GetFoldParent(int line);
void GetHighlightDelimiters(HighlightDelimiter &hDelimiter, int line, int lastLine);
void Indent(bool forwards);
int ExtendWordSelect(int pos, int delta, bool onlyWordCharacters=false);

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
/** @file Editor.h
** Defines the main editor class.
**/
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef EDITOR_H
@ -131,6 +131,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
* When a style attribute is changed, this cache is flushed. */
bool stylesValid;
ViewStyle vs;
Point sizeRGBAImage;
Palette palette;
int printMagnification;
@ -139,6 +140,9 @@ protected: // ScintillaBase subclass needs access to much of Editor
int cursorMode;
int controlCharSymbol;
// Highlight current folding block
HighlightDelimiter highlightDelimiter;
bool hasFocus;
bool hideSelection;
bool inOverstrike;
@ -160,6 +164,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
bool verticalScrollBarVisible;
bool endAtLastLine;
int caretSticky;
int marginOptions;
bool multipleSelection;
bool additionalSelectionTyping;
int multiPasteMode;
@ -191,7 +196,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
int dwellDelay;
int ticksToDwell;
bool dwelling;
enum { selChar, selWord, selLine } selectionType;
enum { selChar, selWord, selSubLine, selWholeLine } selectionType;
Point ptMouseLast;
enum { ddNone, ddInitial, ddDragging } inDragDrop;
bool dropWentOutside;
@ -199,7 +204,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
SelectionPosition posDrop;
int hotSpotClickPos;
int lastXChosen;
int lineAnchor;
int lineAnchorPos;
int originalAnchorPos;
int wordSelectAnchorStartPos;
int wordSelectAnchorEndPos;
@ -332,6 +337,9 @@ protected: // ScintillaBase subclass needs access to much of Editor
virtual void ScrollText(int linesToMove);
void HorizontalScrollTo(int xPos);
void VerticalCentreCaret();
void MoveSelectedLines(int lineDelta);
void MoveSelectedLinesUp();
void MoveSelectedLinesDown();
void MoveCaretInsideView(bool ensureVisible=true);
int DisplayFromPosition(int pos);
@ -367,6 +375,8 @@ protected: // ScintillaBase subclass needs access to much of Editor
int line, int lineEnd, int xStart, int subLine, int subLineStart,
bool overrideBackground, ColourAllocated background,
bool drawWrapMark, ColourAllocated wrapColour);
void DrawIndicator(int indicNum, int startPos, int endPos, Surface *surface, ViewStyle &vsDraw,
int xStart, PRectangle rcLine, LineLayout *ll, int subLine);
void DrawIndicators(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
PRectangle rcLine, LineLayout *ll, int subLine, int lineEnd, bool under);
void DrawAnnotation(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
@ -413,6 +423,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
virtual void NotifyChange() = 0;
virtual void NotifyFocus(bool focus);
virtual void SetCtrlID(int identifier);
virtual int GetCtrlID() { return ctrlID; }
virtual void NotifyParent(SCNotification scn) = 0;
virtual void NotifyStyleToNeeded(int endStyleNeeded);
@ -455,6 +466,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
int StartEndDisplayLine(int pos, bool start);
virtual int KeyCommand(unsigned int iMessage);
virtual int KeyDefault(int /* key */, int /*modifiers*/);
int KeyDownWithModifiers(int key, int modifiers, bool *consumed);
int KeyDown(int key, bool shift, bool ctrl, bool alt, bool *consumed=0);
int GetWhitespaceVisible();
@ -484,7 +496,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
bool PointInSelection(Point pt);
bool PointInSelMargin(Point pt);
Window::Cursor GetMarginCursor(Point pt);
void LineSelection(int lineCurrent_, int lineAnchor_);
void LineSelection(int lineCurrentPos_, int lineAnchorPos_, bool wholeLine);
void WordSelection(int pos);
void DwellEnd(bool mouseMoved);
void MouseLeave();

View File

@ -5,9 +5,17 @@
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <vector>
#include <map>
#ifdef _MSC_VER
#pragma warning(disable: 4786)
#endif
#include "Platform.h"
#include "Scintilla.h"
#include "XPM.h"
#include "Indicator.h"
#ifdef SCI_NAMESPACE
@ -27,6 +35,17 @@ void Indicator::Draw(Surface *surface, const PRectangle &rc, const PRectangle &r
y = 2 - y;
}
surface->LineTo(rc.right, rc.top + y); // Finish the line
} else if (style == INDIC_SQUIGGLELOW) {
surface->MoveTo(rc.left, rc.top);
int x = rc.left + 3;
int y = 0;
while (x < rc.right) {
surface->LineTo(x-1, rc.top + y);
y = 1 - y;
surface->LineTo(x, rc.top + y);
x += 3;
}
surface->LineTo(rc.right, rc.top + y); // Finish the line
} else if (style == INDIC_TT) {
surface->MoveTo(rc.left, ymid);
int x = rc.left + 5;
@ -67,12 +86,47 @@ void Indicator::Draw(Surface *surface, const PRectangle &rc, const PRectangle &r
surface->LineTo(rc.right, rcLine.top+1);
surface->LineTo(rc.left, rcLine.top+1);
surface->LineTo(rc.left, ymid+1);
} else if (style == INDIC_ROUNDBOX) {
} else if (style == INDIC_ROUNDBOX || style == INDIC_STRAIGHTBOX) {
PRectangle rcBox = rcLine;
rcBox.top = rcLine.top + 1;
rcBox.left = rc.left;
rcBox.right = rc.right;
surface->AlphaRectangle(rcBox, 1, fore.allocated, fillAlpha, fore.allocated, 50, 0);
surface->AlphaRectangle(rcBox, (style == INDIC_ROUNDBOX) ? 1 : 0, fore.allocated, fillAlpha, fore.allocated, outlineAlpha, 0);
} else if (style == INDIC_DOTBOX) {
PRectangle rcBox = rcLine;
rcBox.top = rcLine.top + 1;
rcBox.left = rc.left;
rcBox.right = rc.right;
// Cap width at 4000 to avoid large allocations when mistakes made
int width = Platform::Minimum(rcBox.Width(), 4000);
RGBAImage image(width, rcBox.Height(), 0);
// Draw horizontal lines top and bottom
for (int x=0; x<width; x++) {
for (int y=0; y<rcBox.Height(); y += rcBox.Height()-1) {
image.SetPixel(x, y, fore.desired, ((x + y) % 2) ? outlineAlpha : fillAlpha);
}
}
// Draw vertical lines left and right
for (int y=1; y<rcBox.Height(); y++) {
for (int x=0; x<width; x += width-1) {
image.SetPixel(x, y, fore.desired, ((x + y) % 2) ? outlineAlpha : fillAlpha);
}
}
surface->DrawRGBAImage(rcBox, image.GetWidth(), image.GetHeight(), image.Pixels());
} else if (style == INDIC_DASH) {
int x = rc.left;
while (x < rc.right) {
surface->MoveTo(x, ymid);
surface->LineTo(Platform::Minimum(x + 4, rc.right), ymid);
x += 7;
}
} else if (style == INDIC_DOTS) {
int x = rc.left;
while (x < rc.right) {
PRectangle rcDot(x, ymid, x+1, ymid+1);
surface->FillRectangle(rcDot, fore.allocated);
x += 2;
}
} else { // Either INDIC_PLAIN or unknown
surface->MoveTo(rc.left, ymid);
surface->LineTo(rc.right, ymid);

View File

@ -20,7 +20,8 @@ public:
bool under;
ColourPair fore;
int fillAlpha;
Indicator() : style(INDIC_PLAIN), under(false), fore(ColourDesired(0,0,0)), fillAlpha(30) {
int outlineAlpha;
Indicator() : style(INDIC_PLAIN), under(false), fore(ColourDesired(0,0,0)), fillAlpha(30), outlineAlpha(50) {
}
void Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine);
};

View File

@ -66,14 +66,42 @@ unsigned int KeyMap::Find(int key, int modifiers) {
return 0;
}
#if PLAT_GTK_MACOSX
#define OS_X_KEYS 1
#else
#define OS_X_KEYS 0
#endif
// Define a modifier that is exactly Ctrl key on all platforms
// Most uses of Ctrl map to Cmd on OS X but some can't so use SCI_[S]CTRL_META
#if OS_X_KEYS
#define SCI_CTRL_META SCI_META
#define SCI_SCTRL_META (SCI_META | SCI_SHIFT)
#else
#define SCI_CTRL_META SCI_CTRL
#define SCI_SCTRL_META (SCI_CTRL | SCI_SHIFT)
#endif
const KeyToCommand KeyMap::MapDefault[] = {
#if OS_X_KEYS
{SCK_DOWN, SCI_CTRL, SCI_DOCUMENTEND},
{SCK_DOWN, SCI_CSHIFT, SCI_DOCUMENTENDEXTEND},
{SCK_UP, SCI_CTRL, SCI_DOCUMENTSTART},
{SCK_UP, SCI_CSHIFT, SCI_DOCUMENTSTARTEXTEND},
{SCK_LEFT, SCI_CTRL, SCI_VCHOME},
{SCK_LEFT, SCI_CSHIFT, SCI_VCHOMEEXTEND},
{SCK_RIGHT, SCI_CTRL, SCI_LINEEND},
{SCK_RIGHT, SCI_CSHIFT, SCI_LINEENDEXTEND},
#endif
{SCK_DOWN, SCI_NORM, SCI_LINEDOWN},
{SCK_DOWN, SCI_SHIFT, SCI_LINEDOWNEXTEND},
{SCK_DOWN, SCI_CTRL, SCI_LINESCROLLDOWN},
{SCK_DOWN, SCI_CTRL_META, SCI_LINESCROLLDOWN},
{SCK_DOWN, SCI_ASHIFT, SCI_LINEDOWNRECTEXTEND},
{SCK_UP, SCI_NORM, SCI_LINEUP},
{SCK_UP, SCI_SHIFT, SCI_LINEUPEXTEND},
{SCK_UP, SCI_CTRL, SCI_LINESCROLLUP},
{SCK_UP, SCI_CTRL_META, SCI_LINESCROLLUP},
{SCK_UP, SCI_ASHIFT, SCI_LINEUPRECTEXTEND},
{'[', SCI_CTRL, SCI_PARAUP},
{'[', SCI_CSHIFT, SCI_PARAUPEXTEND},
@ -81,13 +109,13 @@ const KeyToCommand KeyMap::MapDefault[] = {
{']', SCI_CSHIFT, SCI_PARADOWNEXTEND},
{SCK_LEFT, SCI_NORM, SCI_CHARLEFT},
{SCK_LEFT, SCI_SHIFT, SCI_CHARLEFTEXTEND},
{SCK_LEFT, SCI_CTRL, SCI_WORDLEFT},
{SCK_LEFT, SCI_CSHIFT, SCI_WORDLEFTEXTEND},
{SCK_LEFT, SCI_CTRL_META, SCI_WORDLEFT},
{SCK_LEFT, SCI_SCTRL_META, SCI_WORDLEFTEXTEND},
{SCK_LEFT, SCI_ASHIFT, SCI_CHARLEFTRECTEXTEND},
{SCK_RIGHT, SCI_NORM, SCI_CHARRIGHT},
{SCK_RIGHT, SCI_SHIFT, SCI_CHARRIGHTEXTEND},
{SCK_RIGHT, SCI_CTRL, SCI_WORDRIGHT},
{SCK_RIGHT, SCI_CSHIFT, SCI_WORDRIGHTEXTEND},
{SCK_RIGHT, SCI_CTRL_META, SCI_WORDRIGHT},
{SCK_RIGHT, SCI_SCTRL_META, SCI_WORDRIGHTEXTEND},
{SCK_RIGHT, SCI_ASHIFT, SCI_CHARRIGHTRECTEXTEND},
{'/', SCI_CTRL, SCI_WORDPARTLEFT},
{'/', SCI_CSHIFT, SCI_WORDPARTLEFTEXTEND},
@ -98,14 +126,12 @@ const KeyToCommand KeyMap::MapDefault[] = {
{SCK_HOME, SCI_CTRL, SCI_DOCUMENTSTART},
{SCK_HOME, SCI_CSHIFT, SCI_DOCUMENTSTARTEXTEND},
{SCK_HOME, SCI_ALT, SCI_HOMEDISPLAY},
// {SCK_HOME, SCI_ASHIFT, SCI_HOMEDISPLAYEXTEND},
{SCK_HOME, SCI_ASHIFT, SCI_VCHOMERECTEXTEND},
{SCK_END, SCI_NORM, SCI_LINEEND},
{SCK_END, SCI_SHIFT, SCI_LINEENDEXTEND},
{SCK_END, SCI_CTRL, SCI_DOCUMENTEND},
{SCK_END, SCI_CSHIFT, SCI_DOCUMENTENDEXTEND},
{SCK_END, SCI_ALT, SCI_LINEENDDISPLAY},
// {SCK_END, SCI_ASHIFT, SCI_LINEENDDISPLAYEXTEND},
{SCK_END, SCI_ASHIFT, SCI_LINEENDRECTEXTEND},
{SCK_PRIOR, SCI_NORM, SCI_PAGEUP},
{SCK_PRIOR, SCI_SHIFT, SCI_PAGEUPEXTEND},
@ -127,7 +153,11 @@ const KeyToCommand KeyMap::MapDefault[] = {
{SCK_BACK, SCI_ALT, SCI_UNDO},
{SCK_BACK, SCI_CSHIFT, SCI_DELLINELEFT},
{'Z', SCI_CTRL, SCI_UNDO},
#if OS_X_KEYS
{'Z', SCI_CSHIFT, SCI_REDO},
#else
{'Y', SCI_CTRL, SCI_REDO},
#endif
{'X', SCI_CTRL, SCI_CUT},
{'C', SCI_CTRL, SCI_COPY},
{'V', SCI_CTRL, SCI_PASTE},
@ -139,7 +169,6 @@ const KeyToCommand KeyMap::MapDefault[] = {
{SCK_ADD, SCI_CTRL, SCI_ZOOMIN},
{SCK_SUBTRACT, SCI_CTRL, SCI_ZOOMOUT},
{SCK_DIVIDE, SCI_CTRL, SCI_SETZOOM},
//'L', SCI_CTRL, SCI_FORMFEED,
{'L', SCI_CTRL, SCI_LINECUT},
{'L', SCI_CSHIFT, SCI_LINEDELETE},
{'T', SCI_CSHIFT, SCI_LINECOPY},

View File

@ -16,6 +16,7 @@ namespace Scintilla {
#define SCI_SHIFT SCMOD_SHIFT
#define SCI_CTRL SCMOD_CTRL
#define SCI_ALT SCMOD_ALT
#define SCI_META SCMOD_META
#define SCI_CSHIFT (SCI_CTRL | SCI_SHIFT)
#define SCI_ASHIFT (SCI_ALT | SCI_SHIFT)

View File

@ -2,11 +2,14 @@
/** @file LineMarker.cxx
** Defines the look of a line marker in the margin .
**/
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <string.h>
#include <vector>
#include <map>
#include "Platform.h"
#include "Scintilla.h"
@ -20,6 +23,7 @@ using namespace Scintilla;
void LineMarker::RefreshColourPalette(Palette &pal, bool want) {
pal.WantFind(fore, want);
pal.WantFind(back, want);
pal.WantFind(backSelected, want);
if (pxpm) {
pxpm->RefreshColourPalette(pal, want);
}
@ -37,6 +41,12 @@ void LineMarker::SetXPM(const char *const *linesForm) {
markType = SC_MARK_PIXMAP;
}
void LineMarker::SetRGBAImage(Point sizeRGBAImage, const unsigned char *pixelsRGBAImage) {
delete image;
image = new RGBAImage(sizeRGBAImage.x, sizeRGBAImage.y, pixelsRGBAImage);
markType = SC_MARK_RGBAIMAGE;
}
static void DrawBox(Surface *surface, int centreX, int centreY, int armSize, ColourAllocated fore, ColourAllocated back) {
PRectangle rc;
rc.left = centreX - armSize;
@ -67,11 +77,39 @@ static void DrawMinus(Surface *surface, int centreX, int centreY, int armSize, C
surface->FillRectangle(rcH, fore);
}
void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharacter) {
void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharacter, typeOfFold tFold) {
ColourPair head = back;
ColourPair body = back;
ColourPair tail = back;
switch (tFold) {
case LineMarker::head :
case LineMarker::headWithTail :
head = backSelected;
tail = backSelected;
break;
case LineMarker::body :
head = backSelected;
body = backSelected;
break;
case LineMarker::tail :
body = backSelected;
tail = backSelected;
break;
default :
// LineMarker::undefined
break;
}
if ((markType == SC_MARK_PIXMAP) && (pxpm)) {
pxpm->Draw(surface, rcWhole);
return;
}
if ((markType == SC_MARK_RGBAIMAGE) && (image)) {
surface->DrawRGBAImage(rcWhole, image->GetWidth(), image->GetHeight(), image->Pixels());
return;
}
// Restrict most shapes a bit
PRectangle rc = rcWhole;
rc.top++;
@ -159,106 +197,145 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharac
// An invisible marker so don't draw anything
} else if (markType == SC_MARK_VLINE) {
surface->PenColour(back.allocated);
surface->PenColour(body.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, rcWhole.bottom);
} else if (markType == SC_MARK_LCORNER) {
surface->PenColour(back.allocated);
surface->PenColour(tail.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, rc.top + dimOn2);
surface->LineTo(rc.right - 2, rc.top + dimOn2);
} else if (markType == SC_MARK_TCORNER) {
surface->PenColour(back.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, rcWhole.bottom);
surface->PenColour(tail.allocated);
surface->MoveTo(centreX, rc.top + dimOn2);
surface->LineTo(rc.right - 2, rc.top + dimOn2);
surface->PenColour(body.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, rc.top + dimOn2 + 1);
surface->PenColour(head.allocated);
surface->LineTo(centreX, rcWhole.bottom);
} else if (markType == SC_MARK_LCORNERCURVE) {
surface->PenColour(back.allocated);
surface->PenColour(tail.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, rc.top + dimOn2-3);
surface->LineTo(centreX+3, rc.top + dimOn2);
surface->LineTo(rc.right - 1, rc.top + dimOn2);
} else if (markType == SC_MARK_TCORNERCURVE) {
surface->PenColour(back.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, rcWhole.bottom);
surface->PenColour(tail.allocated);
surface->MoveTo(centreX, rc.top + dimOn2-3);
surface->LineTo(centreX+3, rc.top + dimOn2);
surface->LineTo(rc.right - 1, rc.top + dimOn2);
surface->PenColour(body.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, rc.top + dimOn2-2);
surface->PenColour(head.allocated);
surface->LineTo(centreX, rcWhole.bottom);
} else if (markType == SC_MARK_BOXPLUS) {
surface->PenColour(back.allocated);
DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
DrawBox(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
DrawPlus(surface, centreX, centreY, blobSize, tail.allocated);
} else if (markType == SC_MARK_BOXPLUSCONNECTED) {
surface->PenColour(back.allocated);
DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
if (tFold == LineMarker::headWithTail)
surface->PenColour(tail.allocated);
else
surface->PenColour(body.allocated);
surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, rcWhole.bottom);
surface->PenColour(body.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, centreY - blobSize);
} else if (markType == SC_MARK_BOXMINUS) {
surface->PenColour(back.allocated);
DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
DrawBox(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
DrawPlus(surface, centreX, centreY, blobSize, tail.allocated);
if (tFold == LineMarker::body) {
surface->PenColour(tail.allocated);
surface->MoveTo(centreX + 1, centreY + blobSize);
surface->LineTo(centreX + blobSize + 1, centreY + blobSize);
surface->MoveTo(centreX + blobSize, centreY + blobSize);
surface->LineTo(centreX + blobSize, centreY - blobSize);
surface->MoveTo(centreX + 1, centreY - blobSize);
surface->LineTo(centreX + blobSize + 1, centreY - blobSize);
}
} else if (markType == SC_MARK_BOXMINUS) {
DrawBox(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
DrawMinus(surface, centreX, centreY, blobSize, tail.allocated);
surface->PenColour(head.allocated);
surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, rcWhole.bottom);
} else if (markType == SC_MARK_BOXMINUSCONNECTED) {
surface->PenColour(back.allocated);
DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
DrawBox(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
DrawMinus(surface, centreX, centreY, blobSize, tail.allocated);
surface->PenColour(head.allocated);
surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, rcWhole.bottom);
surface->PenColour(body.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, centreY - blobSize);
if (tFold == LineMarker::body) {
surface->PenColour(tail.allocated);
surface->MoveTo(centreX + 1, centreY + blobSize);
surface->LineTo(centreX + blobSize + 1, centreY + blobSize);
surface->MoveTo(centreX + blobSize, centreY + blobSize);
surface->LineTo(centreX + blobSize, centreY - blobSize);
surface->MoveTo(centreX + 1, centreY - blobSize);
surface->LineTo(centreX + blobSize + 1, centreY - blobSize);
}
} else if (markType == SC_MARK_CIRCLEPLUS) {
DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
surface->PenColour(back.allocated);
DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
DrawPlus(surface, centreX, centreY, blobSize, tail.allocated);
} else if (markType == SC_MARK_CIRCLEPLUSCONNECTED) {
DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
surface->PenColour(back.allocated);
DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
if (tFold == LineMarker::headWithTail)
surface->PenColour(tail.allocated);
else
surface->PenColour(body.allocated);
surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, rcWhole.bottom);
surface->PenColour(body.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, centreY - blobSize);
} else if (markType == SC_MARK_CIRCLEMINUS) {
DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
surface->PenColour(back.allocated);
DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
DrawPlus(surface, centreX, centreY, blobSize, tail.allocated);
} else if (markType == SC_MARK_CIRCLEMINUS) {
DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
DrawMinus(surface, centreX, centreY, blobSize, tail.allocated);
surface->PenColour(head.allocated);
surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, rcWhole.bottom);
} else if (markType == SC_MARK_CIRCLEMINUSCONNECTED) {
DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
surface->PenColour(back.allocated);
DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
DrawMinus(surface, centreX, centreY, blobSize, tail.allocated);
surface->PenColour(head.allocated);
surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, rcWhole.bottom);
surface->PenColour(body.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, centreY - blobSize);

View File

@ -2,7 +2,7 @@
/** @file LineMarker.h
** Defines the look of a line marker in the margin .
**/
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef LINEMARKER_H
@ -12,47 +12,61 @@
namespace Scintilla {
#endif
/**
*/
class LineMarker {
public:
enum typeOfFold { undefined, head, body, tail, headWithTail };
int markType;
ColourPair fore;
ColourPair back;
ColourPair backSelected;
int alpha;
XPM *pxpm;
RGBAImage *image;
LineMarker() {
markType = SC_MARK_CIRCLE;
fore = ColourDesired(0,0,0);
back = ColourDesired(0xff,0xff,0xff);
backSelected = ColourDesired(0xff,0x00,0x00);
alpha = SC_ALPHA_NOALPHA;
pxpm = NULL;
image = NULL;
}
LineMarker(const LineMarker &) {
// Defined to avoid pxpm being blindly copied, not as real copy constructor
markType = SC_MARK_CIRCLE;
fore = ColourDesired(0,0,0);
back = ColourDesired(0xff,0xff,0xff);
backSelected = ColourDesired(0xff,0x00,0x00);
alpha = SC_ALPHA_NOALPHA;
pxpm = NULL;
image = NULL;
}
~LineMarker() {
delete pxpm;
delete image;
}
LineMarker &operator=(const LineMarker &) {
// Defined to avoid pxpm being blindly copied, not as real assignment operator
markType = SC_MARK_CIRCLE;
fore = ColourDesired(0,0,0);
back = ColourDesired(0xff,0xff,0xff);
backSelected = ColourDesired(0xff,0x00,0x00);
alpha = SC_ALPHA_NOALPHA;
delete pxpm;
pxpm = NULL;
delete image;
image = NULL;
return *this;
}
void RefreshColourPalette(Palette &pal, bool want);
void SetXPM(const char *textForm);
void SetXPM(const char *const *linesForm);
void Draw(Surface *surface, PRectangle &rc, Font &fontForCharacter);
void SetRGBAImage(Point sizeRGBAImage, const unsigned char *pixelsRGBAImage);
void Draw(Surface *surface, PRectangle &rc, Font &fontForCharacter, typeOfFold tFold);
};
#ifdef SCI_NAMESPACE

View File

@ -425,10 +425,10 @@ void LineAnnotation::SetText(int line, const char *text) {
if (annotations[line]) {
delete []annotations[line];
}
annotations[line] = AllocateAnnotation(strlen(text), style);
annotations[line] = AllocateAnnotation(static_cast<int>(strlen(text)), style);
AnnotationHeader *pah = reinterpret_cast<AnnotationHeader *>(annotations[line]);
pah->style = static_cast<short>(style);
pah->length = strlen(text);
pah->length = static_cast<int>(strlen(text));
pah->lines = static_cast<short>(NumberLines(text));
memcpy(annotations[line]+sizeof(AnnotationHeader), text, pah->length);
} else {

View File

@ -12,6 +12,7 @@
#include <string>
#include <vector>
#include <map>
#include "Platform.h"
@ -151,15 +152,15 @@ void LineLayout::SetLineStart(int line, int start) {
}
void LineLayout::SetBracesHighlight(Range rangeLine, Position braces[],
char bracesMatchStyle, int xHighlight) {
if (rangeLine.ContainsCharacter(braces[0])) {
char bracesMatchStyle, int xHighlight, bool ignoreStyle) {
if (!ignoreStyle && rangeLine.ContainsCharacter(braces[0])) {
int braceOffset = braces[0] - rangeLine.start;
if (braceOffset < numCharsInLine) {
bracePreviousStyles[0] = styles[braceOffset];
styles[braceOffset] = bracesMatchStyle;
}
}
if (rangeLine.ContainsCharacter(braces[1])) {
if (!ignoreStyle && rangeLine.ContainsCharacter(braces[1])) {
int braceOffset = braces[1] - rangeLine.start;
if (braceOffset < numCharsInLine) {
bracePreviousStyles[1] = styles[braceOffset];
@ -172,14 +173,14 @@ void LineLayout::SetBracesHighlight(Range rangeLine, Position braces[],
}
}
void LineLayout::RestoreBracesHighlight(Range rangeLine, Position braces[]) {
if (rangeLine.ContainsCharacter(braces[0])) {
void LineLayout::RestoreBracesHighlight(Range rangeLine, Position braces[], bool ignoreStyle) {
if (!ignoreStyle && rangeLine.ContainsCharacter(braces[0])) {
int braceOffset = braces[0] - rangeLine.start;
if (braceOffset < numCharsInLine) {
styles[braceOffset] = bracePreviousStyles[0];
}
}
if (rangeLine.ContainsCharacter(braces[1])) {
if (!ignoreStyle && rangeLine.ContainsCharacter(braces[1])) {
int braceOffset = braces[1] - rangeLine.start;
if (braceOffset < numCharsInLine) {
styles[braceOffset] = bracePreviousStyles[1];
@ -391,18 +392,19 @@ static int NextBadU(const char *s, int p, int len, int &trailBytes) {
return -1;
}
BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_, bool utf8_, int xStart, bool breakForSelection) :
BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_,
int xStart, bool breakForSelection, Document *pdoc_) :
ll(ll_),
lineStart(lineStart_),
lineEnd(lineEnd_),
posLineStart(posLineStart_),
utf8(utf8_),
nextBreak(lineStart_),
saeSize(0),
saeLen(0),
saeCurrentPos(0),
saeNext(0),
subBreak(-1) {
subBreak(-1),
pdoc(pdoc_) {
saeSize = 8;
selAndEdge = new int[saeSize];
for (unsigned int j=0; j < saeSize; j++) {
@ -435,7 +437,7 @@ BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posL
Insert(ll->edgeColumn - 1);
Insert(lineEnd - 1);
if (utf8) {
if (pdoc && (SC_CP_UTF8 == pdoc->dbcsCodePage)) {
int trailBytes=0;
for (int pos = -1;;) {
pos = NextBadU(ll->chars, pos, lineEnd, trailBytes);
@ -456,10 +458,6 @@ int BreakFinder::First() const {
return nextBreak;
}
static bool IsTrailByte(int ch) {
return (ch >= 0x80) && (ch < (0x80 + 0x40));
}
int BreakFinder::Next() {
if (subBreak == -1) {
int prev = nextBreak;
@ -490,34 +488,7 @@ int BreakFinder::Next() {
subBreak = -1;
return nextBreak;
} else {
int lastGoodBreak = -1;
int lastOKBreak = -1;
int lastUTF8Break = -1;
int j;
for (j = subBreak + 1; j <= nextBreak; j++) {
if (IsSpaceOrTab(ll->chars[j - 1]) && !IsSpaceOrTab(ll->chars[j])) {
lastGoodBreak = j;
}
if (static_cast<unsigned char>(ll->chars[j]) < 'A') {
lastOKBreak = j;
}
if (utf8 && !IsTrailByte(static_cast<unsigned char>(ll->chars[j]))) {
lastUTF8Break = j;
}
if (((j - subBreak) >= lengthEachSubdivision) &&
((lastGoodBreak >= 0) || (lastOKBreak >= 0) || (lastUTF8Break >= 0))) {
break;
}
}
if (lastGoodBreak >= 0) {
subBreak = lastGoodBreak;
} else if (lastOKBreak >= 0) {
subBreak = lastOKBreak;
} else if (lastUTF8Break >= 0) {
subBreak = lastUTF8Break;
} else {
subBreak = nextBreak;
}
subBreak += pdoc->SafeSegment(ll->chars + subBreak, nextBreak-subBreak, lengthEachSubdivision);
if (subBreak >= nextBreak) {
subBreak = -1;
return nextBreak;
@ -571,16 +542,16 @@ bool PositionCacheEntry::Retrieve(unsigned int styleNumber_, const char *s_,
}
}
int PositionCacheEntry::Hash(unsigned int styleNumber, const char *s, unsigned int len) {
int PositionCacheEntry::Hash(unsigned int styleNumber_, const char *s, unsigned int len_) {
unsigned int ret = s[0] << 7;
for (unsigned int i=0; i<len; i++) {
for (unsigned int i=0; i<len_; i++) {
ret *= 1000003;
ret ^= s[i];
}
ret *= 1000003;
ret ^= len;
ret ^= len_;
ret *= 1000003;
ret ^= styleNumber;
ret ^= styleNumber_;
return ret;
}
@ -624,7 +595,8 @@ void PositionCache::SetSize(size_t size_) {
}
void PositionCache::MeasureWidths(Surface *surface, ViewStyle &vstyle, unsigned int styleNumber,
const char *s, unsigned int len, int *positions) {
const char *s, unsigned int len, int *positions, Document *pdoc) {
allClear = false;
int probe = -1;
if ((size > 0) && (len < 30)) {
@ -633,11 +605,11 @@ void PositionCache::MeasureWidths(Surface *surface, ViewStyle &vstyle, unsigned
// Two way associative: try two probe positions.
int hashValue = PositionCacheEntry::Hash(styleNumber, s, len);
probe = hashValue % size;
probe = static_cast<int>(hashValue % size);
if (pces[probe].Retrieve(styleNumber, s, len, positions)) {
return;
}
int probe2 = (hashValue * 37) % size;
int probe2 = static_cast<int>((hashValue * 37) % size);
if (pces[probe2].Retrieve(styleNumber, s, len, positions)) {
return;
}
@ -646,7 +618,22 @@ void PositionCache::MeasureWidths(Surface *surface, ViewStyle &vstyle, unsigned
probe = probe2;
}
}
surface->MeasureWidths(vstyle.styles[styleNumber].font, s, len, positions);
if (len > BreakFinder::lengthStartSubdivision) {
// Break up into segments
unsigned int startSegment = 0;
int xStartSegment = 0;
while (startSegment < len) {
unsigned int lenSegment = pdoc->SafeSegment(s + startSegment, len - startSegment, BreakFinder::lengthEachSubdivision);
surface->MeasureWidths(vstyle.styles[styleNumber].font, s + startSegment, lenSegment, positions + startSegment);
for (unsigned int inSeg = 0; inSeg < lenSegment; inSeg++) {
positions[startSegment + inSeg] += xStartSegment;
}
xStartSegment = positions[startSegment + lenSegment - 1];
startSegment += lenSegment;
}
} else {
surface->MeasureWidths(vstyle.styles[styleNumber].font, s, len, positions);
}
if (probe >= 0) {
clock++;
if (clock > 60000) {

View File

@ -63,8 +63,8 @@ public:
bool InLine(int offset, int line) const;
void SetLineStart(int line, int start);
void SetBracesHighlight(Range rangeLine, Position braces[],
char bracesMatchStyle, int xHighlight);
void RestoreBracesHighlight(Range rangeLine, Position braces[]);
char bracesMatchStyle, int xHighlight, bool ignoreStyle);
void RestoreBracesHighlight(Range rangeLine, Position braces[], bool ignoreStyle);
int FindBefore(int x, int lower, int upper) const;
int EndLineStyle() const;
};
@ -110,23 +110,17 @@ public:
void Set(unsigned int styleNumber_, const char *s_, unsigned int len_, int *positions_, unsigned int clock);
void Clear();
bool Retrieve(unsigned int styleNumber_, const char *s_, unsigned int len_, int *positions_) const;
static int Hash(unsigned int styleNumber, const char *s, unsigned int len);
static int Hash(unsigned int styleNumber_, const char *s, unsigned int len);
bool NewerThan(const PositionCacheEntry &other) const;
void ResetClock();
};
// Class to break a line of text into shorter runs at sensible places.
class BreakFinder {
// If a whole run is longer than lengthStartSubdivision then subdivide
// into smaller runs at spaces or punctuation.
enum { lengthStartSubdivision = 300 };
// Try to make each subdivided run lengthEachSubdivision or shorter.
enum { lengthEachSubdivision = 100 };
LineLayout *ll;
int lineStart;
int lineEnd;
int posLineStart;
bool utf8;
int nextBreak;
int *selAndEdge;
unsigned int saeSize;
@ -134,9 +128,16 @@ class BreakFinder {
unsigned int saeCurrentPos;
int saeNext;
int subBreak;
Document *pdoc;
void Insert(int val);
public:
BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_, bool utf8_, int xStart, bool breakForSelection);
// If a whole run is longer than lengthStartSubdivision then subdivide
// into smaller runs at spaces or punctuation.
enum { lengthStartSubdivision = 300 };
// Try to make each subdivided run lengthEachSubdivision or shorter.
enum { lengthEachSubdivision = 100 };
BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_,
int xStart, bool breakForSelection, Document *pdoc_);
~BreakFinder();
int First() const;
int Next();
@ -152,9 +153,9 @@ public:
~PositionCache();
void Clear();
void SetSize(size_t size_);
int GetSize() const { return size; }
size_t GetSize() const { return size; }
void MeasureWidths(Surface *surface, ViewStyle &vstyle, unsigned int styleNumber,
const char *s, unsigned int len, int *positions);
const char *s, unsigned int len, int *positions, Document *pdoc);
};
inline bool IsSpaceOrTab(int ch) {

View File

@ -321,7 +321,7 @@ void RESearch::ChSetWithCase(unsigned char c, bool caseSensitive) {
}
}
const unsigned char escapeValue(unsigned char ch) {
unsigned char escapeValue(unsigned char ch) {
switch (ch) {
case 'a': return '\a';
case 'b': return '\b';
@ -888,10 +888,10 @@ int RESearch::PMatch(CharacterIndexer &ci, int lp, int endp, char *ap) {
return NOTFOUND;
break;
case BOT:
bopat[*ap++] = lp;
bopat[static_cast<int>(*ap++)] = lp;
break;
case EOT:
eopat[*ap++] = lp;
eopat[static_cast<int>(*ap++)] = lp;
break;
case BOW:
if ((lp!=bol && iswordc(ci.CharAt(lp-1))) || !iswordc(ci.CharAt(lp)))

View File

@ -21,7 +21,7 @@ using namespace Scintilla;
#endif
// Find the first run at a position
int RunStyles::RunFromPosition(int position) {
int RunStyles::RunFromPosition(int position) const {
int run = starts->PartitionFromPosition(position);
// Go to first element with this position
while ((run > 0) && (position == starts->PositionFromPartition(run-1))) {
@ -147,6 +147,8 @@ bool RunStyles::FillRange(int &position, int value, int &fillLength) {
runEnd = RunFromPosition(end);
RemoveRunIfSameAsPrevious(runEnd);
RemoveRunIfSameAsPrevious(runStart);
runEnd = RunFromPosition(end);
RemoveRunIfEmpty(runEnd);
return true;
} else {
return false;
@ -216,3 +218,33 @@ void RunStyles::DeleteRange(int position, int deleteLength) {
}
}
int RunStyles::Runs() const {
return starts->Partitions();
}
bool RunStyles::AllSame() const {
for (int run = 1; run < starts->Partitions(); run++) {
if (styles->ValueAt(run) != styles->ValueAt(run - 1))
return false;
}
return true;
}
bool RunStyles::AllSameAs(int value) const {
return AllSame() && (styles->ValueAt(0) == value);
}
int RunStyles::Find(int value, int start) const {
if (start < Length()) {
int run = start ? RunFromPosition(start) : 0;
if (styles->ValueAt(run) == value)
return start;
run++;
while (run < starts->Partitions()) {
if (styles->ValueAt(run) == value)
return starts->PositionFromPartition(run);
run++;
}
}
return -1;
}

View File

@ -15,10 +15,10 @@ namespace Scintilla {
#endif
class RunStyles {
public:
private:
Partitioning *starts;
SplitVector<int> *styles;
int RunFromPosition(int position);
int RunFromPosition(int position) const;
int SplitRun(int position);
void RemoveRun(int run);
void RemoveRunIfEmpty(int run);
@ -37,6 +37,10 @@ public:
void InsertSpace(int position, int insertLength);
void DeleteAll();
void DeleteRange(int position, int deleteLength);
int Runs() const;
bool AllSame() const;
bool AllSameAs(int value) const;
int Find(int value, int start) const;
};
#ifdef SCI_NAMESPACE

View File

@ -13,6 +13,7 @@
#include <string>
#include <vector>
#include <map>
#include "Platform.h"
@ -135,16 +136,16 @@ int ScintillaBase::KeyCommand(unsigned int iMessage) {
AutoCompleteMove(1);
return 0;
case SCI_LINEUP:
AutoCompleteMove( -1);
AutoCompleteMove(-1);
return 0;
case SCI_PAGEDOWN:
AutoCompleteMove(5);
return 0;
case SCI_PAGEUP:
AutoCompleteMove( -5);
AutoCompleteMove(-5);
return 0;
case SCI_VCHOME:
AutoCompleteMove( -5000);
AutoCompleteMove(-5000);
return 0;
case SCI_LINEEND:
AutoCompleteMove(5000);
@ -204,7 +205,8 @@ void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) {
if (ac.chooseSingle && (listType == 0)) {
if (list && !strchr(list, ac.GetSeparator())) {
const char *typeSep = strchr(list, ac.GetTypesep());
size_t lenInsert = (typeSep) ? (typeSep-list) : strlen(list);
int lenInsert = typeSep ?
static_cast<int>(typeSep-list) : static_cast<int>(strlen(list));
if (ac.ignoreCase) {
SetEmptySelection(sel.MainCaret() - lenEntered);
pdoc->DeleteChars(sel.MainCaret(), lenEntered);
@ -349,6 +351,7 @@ void ScintillaBase::AutoCompleteCompleted() {
scn.wParam = listType;
scn.listType = listType;
Position firstPos = ac.posStart - ac.startLen;
scn.position = firstPos;
scn.lParam = firstPos;
scn.text = selected;
NotifyParent(scn);
@ -392,7 +395,7 @@ int ScintillaBase::AutoCompleteGetCurrentText(char *buffer) {
ac.lb->GetValue(item, selected, sizeof(selected));
if (buffer != NULL)
strcpy(buffer, selected);
return strlen(selected);
return static_cast<int>(strlen(selected));
}
}
if (buffer != NULL)
@ -759,6 +762,10 @@ sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPara
ac.lb->RegisterImage(wParam, reinterpret_cast<const char *>(lParam));
break;
case SCI_REGISTERRGBAIMAGE:
ac.lb->RegisterRGBAImage(wParam, sizeRGBAImage.x, sizeRGBAImage.y, reinterpret_cast<unsigned char *>(lParam));
break;
case SCI_CLEARREGISTEREDIMAGES:
ac.lb->ClearRegisteredImages();
break;

View File

@ -16,14 +16,51 @@
using namespace Scintilla;
#endif
Style::Style() {
aliasOfDefaultFont = true;
FontAlias::FontAlias() {
}
FontAlias::~FontAlias() {
SetID(0);
// ~Font will not release the actual font resource sine it is now 0
}
void FontAlias::MakeAlias(Font &fontOrigin) {
SetID(fontOrigin.GetID());
}
void FontAlias::ClearFont() {
SetID(0);
}
bool FontSpecification::EqualTo(const FontSpecification &other) const {
return bold == other.bold &&
italic == other.italic &&
size == other.size &&
characterSet == other.characterSet &&
fontName == other.fontName;
}
FontMeasurements::FontMeasurements() {
Clear();
}
void FontMeasurements::Clear() {
lineHeight = 2;
ascent = 1;
descent = 1;
externalLeading = 0;
aveCharWidth = 1;
spaceWidth = 1;
sizeZoomed = 2;
}
Style::Style() : FontSpecification() {
Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff),
Platform::DefaultFontSize(), 0, SC_CHARSET_DEFAULT,
false, false, false, false, caseMixed, true, true, false);
}
Style::Style(const Style &source) {
Style::Style(const Style &source) : FontSpecification(), FontMeasurements() {
Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff),
0, 0, 0,
false, false, false, false, caseMixed, true, true, false);
@ -42,11 +79,6 @@ Style::Style(const Style &source) {
}
Style::~Style() {
if (aliasOfDefaultFont)
font.SetID(0);
else
font.Release();
aliasOfDefaultFont = false;
}
Style &Style::operator=(const Style &source) {
@ -70,10 +102,10 @@ Style &Style::operator=(const Style &source) {
}
void Style::Clear(ColourDesired fore_, ColourDesired back_, int size_,
const char *fontName_, int characterSet_,
bool bold_, bool italic_, bool eolFilled_,
bool underline_, ecaseForced caseForce_,
bool visible_, bool changeable_, bool hotspot_) {
const char *fontName_, int characterSet_,
bool bold_, bool italic_, bool eolFilled_,
bool underline_, ecaseForced caseForce_,
bool visible_, bool changeable_, bool hotspot_) {
fore.desired = fore_;
back.desired = back_;
characterSet = characterSet_;
@ -87,79 +119,31 @@ void Style::Clear(ColourDesired fore_, ColourDesired back_, int size_,
visible = visible_;
changeable = changeable_;
hotspot = hotspot_;
if (aliasOfDefaultFont)
font.SetID(0);
else
font.Release();
aliasOfDefaultFont = false;
sizeZoomed = 2;
lineHeight = 2;
ascent = 1;
descent = 1;
externalLeading = 0;
aveCharWidth = 1;
spaceWidth = 1;
font.ClearFont();
FontMeasurements::Clear();
}
void Style::ClearTo(const Style &source) {
Clear(
source.fore.desired,
source.back.desired,
source.size,
source.fontName,
source.characterSet,
source.bold,
source.italic,
source.eolFilled,
source.underline,
source.caseForce,
source.visible,
source.changeable,
source.hotspot);
source.fore.desired,
source.back.desired,
source.size,
source.fontName,
source.characterSet,
source.bold,
source.italic,
source.eolFilled,
source.underline,
source.caseForce,
source.visible,
source.changeable,
source.hotspot);
}
bool Style::EquivalentFontTo(const Style *other) const {
if (bold != other->bold ||
italic != other->italic ||
size != other->size ||
characterSet != other->characterSet)
return false;
if (fontName == other->fontName)
return true;
if (!fontName)
return false;
if (!other->fontName)
return false;
return strcmp(fontName, other->fontName) == 0;
}
void Style::Realise(Surface &surface, int zoomLevel, Style *defaultStyle, int extraFontFlag) {
sizeZoomed = size + zoomLevel;
if (sizeZoomed <= 2) // Hangs if sizeZoomed <= 1
sizeZoomed = 2;
if (aliasOfDefaultFont)
font.SetID(0);
else
font.Release();
int deviceHeight = surface.DeviceHeightFont(sizeZoomed);
aliasOfDefaultFont = defaultStyle &&
(EquivalentFontTo(defaultStyle) || !fontName);
if (aliasOfDefaultFont) {
font.SetID(defaultStyle->font.GetID());
} else if (fontName) {
font.Create(fontName, characterSet, deviceHeight, bold, italic, extraFontFlag);
} else {
font.SetID(0);
}
ascent = surface.Ascent(font);
descent = surface.Descent(font);
// Probably more typographically correct to include leading
// but that means more complex drawing as leading must be erased
//lineHeight = surface.ExternalLeading() + surface.Height();
externalLeading = surface.ExternalLeading(font);
lineHeight = surface.Height(font);
aveCharWidth = surface.AverageCharWidth(font);
spaceWidth = surface.WidthChar(font, ' ');
void Style::Copy(Font &font_, const FontMeasurements &fm_) {
font.MakeAlias(font_);
#if PLAT_WX
font.SetAscent(fm_.ascent);
#endif
(FontMeasurements &)(*this) = fm_;
}

View File

@ -12,18 +12,54 @@
namespace Scintilla {
#endif
/**
*/
class Style {
public:
ColourPair fore;
ColourPair back;
bool aliasOfDefaultFont;
struct FontSpecification {
const char *fontName;
bool bold;
bool italic;
int size;
const char *fontName;
int characterSet;
int extraFontFlag;
FontSpecification() :
fontName(0),
bold(false),
italic(false),
size(10),
characterSet(0),
extraFontFlag(0) {
}
bool EqualTo(const FontSpecification &other) const;
};
// Just like Font but only has a copy of the FontID so should not delete it
class FontAlias : public Font {
// Private so FontAlias objects can not be copied
FontAlias(const FontAlias &);
FontAlias &operator=(const FontAlias &);
public:
FontAlias();
virtual ~FontAlias();
void MakeAlias(Font &fontOrigin);
void ClearFont();
};
struct FontMeasurements {
unsigned int lineHeight;
unsigned int ascent;
unsigned int descent;
unsigned int externalLeading;
unsigned int aveCharWidth;
unsigned int spaceWidth;
int sizeZoomed;
FontMeasurements();
void Clear();
};
/**
*/
class Style : public FontSpecification, public FontMeasurements {
public:
ColourPair fore;
ColourPair back;
bool eolFilled;
bool underline;
enum ecaseForced {caseMixed, caseUpper, caseLower};
@ -32,14 +68,7 @@ public:
bool changeable;
bool hotspot;
Font font;
int sizeZoomed;
unsigned int lineHeight;
unsigned int ascent;
unsigned int descent;
unsigned int externalLeading;
unsigned int aveCharWidth;
unsigned int spaceWidth;
FontAlias font;
Style();
Style(const Style &source);
@ -52,8 +81,7 @@ public:
bool underline_, ecaseForced caseForce_,
bool visible_, bool changeable_, bool hotspot_);
void ClearTo(const Style &source);
bool EquivalentFontTo(const Style *other) const;
void Realise(Surface &surface, int zoomLevel, Style *defaultStyle = 0, int extraFontFlag = 0);
void Copy(Font &font_, const FontMeasurements &fm_);
bool IsProtected() const { return !(changeable && visible);}
};

View File

@ -7,6 +7,9 @@
#include <string.h>
#include <vector>
#include <map>
#include "Platform.h"
#include "Scintilla.h"
@ -72,11 +75,66 @@ const char *FontNames::Save(const char *name) {
return names[max-1];
}
FontRealised::FontRealised(const FontSpecification &fs) {
frNext = NULL;
(FontSpecification &)(*this) = fs;
}
FontRealised::~FontRealised() {
font.Release();
delete frNext;
frNext = 0;
}
void FontRealised::Realise(Surface &surface, int zoomLevel) {
PLATFORM_ASSERT(fontName);
sizeZoomed = size + zoomLevel;
if (sizeZoomed <= 2) // Hangs if sizeZoomed <= 1
sizeZoomed = 2;
int deviceHeight = surface.DeviceHeightFont(sizeZoomed);
font.Create(fontName, characterSet, deviceHeight, bold, italic, extraFontFlag);
ascent = surface.Ascent(font);
descent = surface.Descent(font);
externalLeading = surface.ExternalLeading(font);
lineHeight = surface.Height(font);
aveCharWidth = surface.AverageCharWidth(font);
spaceWidth = surface.WidthChar(font, ' ');
if (frNext) {
frNext->Realise(surface, zoomLevel);
}
}
FontRealised *FontRealised::Find(const FontSpecification &fs) {
if (!fs.fontName)
return this;
FontRealised *fr = this;
while (fr) {
if (fr->EqualTo(fs))
return fr;
fr = fr->frNext;
}
return 0;
}
void FontRealised::FindMaxAscentDescent(unsigned int &maxAscent, unsigned int &maxDescent) {
FontRealised *fr = this;
while (fr) {
if (maxAscent < fr->ascent)
maxAscent = fr->ascent;
if (maxDescent < fr->descent)
maxDescent = fr->descent;
fr = fr->frNext;
}
}
ViewStyle::ViewStyle() {
Init();
}
ViewStyle::ViewStyle(const ViewStyle &source) {
frFirst = NULL;
Init(source.stylesSize);
for (unsigned int sty=0; sty<source.stylesSize; sty++) {
styles[sty] = source.styles[sty];
@ -150,14 +208,21 @@ ViewStyle::ViewStyle(const ViewStyle &source) {
marginStyleOffset = source.marginStyleOffset;
annotationVisible = source.annotationVisible;
annotationStyleOffset = source.annotationStyleOffset;
braceHighlightIndicatorSet = source.braceHighlightIndicatorSet;
braceHighlightIndicator = source.braceHighlightIndicator;
braceBadLightIndicatorSet = source.braceBadLightIndicatorSet;
braceBadLightIndicator = source.braceBadLightIndicator;
}
ViewStyle::~ViewStyle() {
delete []styles;
styles = NULL;
delete frFirst;
frFirst = NULL;
}
void ViewStyle::Init(size_t stylesSize_) {
frFirst = NULL;
stylesSize = 0;
styles = NULL;
AllocStyles(stylesSize_);
@ -255,6 +320,10 @@ void ViewStyle::Init(size_t stylesSize_) {
marginStyleOffset = 0;
annotationVisible = ANNOTATION_HIDDEN;
annotationStyleOffset = 0;
braceHighlightIndicatorSet = false;
braceHighlightIndicator = 0;
braceBadLightIndicatorSet = false;
braceBadLightIndicator = 0;
}
void ViewStyle::RefreshColourPalette(Palette &pal, bool want) {
@ -290,33 +359,59 @@ void ViewStyle::RefreshColourPalette(Palette &pal, bool want) {
pal.WantFind(hotspotBackground, want);
}
void ViewStyle::CreateFont(const FontSpecification &fs) {
if (fs.fontName) {
for (FontRealised *cur=frFirst; cur; cur=cur->frNext) {
if (cur->EqualTo(fs))
return;
if (!cur->frNext) {
cur->frNext = new FontRealised(fs);
return;
}
}
frFirst = new FontRealised(fs);
}
}
void ViewStyle::Refresh(Surface &surface) {
delete frFirst;
frFirst = NULL;
selbar.desired = Platform::Chrome();
selbarlight.desired = Platform::ChromeHighlight();
styles[STYLE_DEFAULT].Realise(surface, zoomLevel, NULL, extraFontFlag);
maxAscent = styles[STYLE_DEFAULT].ascent;
maxDescent = styles[STYLE_DEFAULT].descent;
for (unsigned int i=0; i<stylesSize; i++) {
styles[i].extraFontFlag = extraFontFlag;
}
CreateFont(styles[STYLE_DEFAULT]);
for (unsigned int j=0; j<stylesSize; j++) {
CreateFont(styles[j]);
}
frFirst->Realise(surface, zoomLevel);
for (unsigned int k=0; k<stylesSize; k++) {
FontRealised *fr = frFirst->Find(styles[k]);
styles[k].Copy(fr->font, *fr);
}
maxAscent = 1;
maxDescent = 1;
frFirst->FindMaxAscentDescent(maxAscent, maxDescent);
maxAscent += extraAscent;
maxDescent += extraDescent;
lineHeight = maxAscent + maxDescent;
someStylesProtected = false;
someStylesForceCase = false;
for (unsigned int i=0; i<stylesSize; i++) {
if (i != STYLE_DEFAULT) {
styles[i].Realise(surface, zoomLevel, &styles[STYLE_DEFAULT], extraFontFlag);
if (maxAscent < styles[i].ascent)
maxAscent = styles[i].ascent;
if (maxDescent < styles[i].descent)
maxDescent = styles[i].descent;
}
if (styles[i].IsProtected()) {
for (unsigned int l=0; l<stylesSize; l++) {
if (styles[l].IsProtected()) {
someStylesProtected = true;
}
if (styles[i].caseForce != Style::caseMixed) {
if (styles[l].caseForce != Style::caseMixed) {
someStylesForceCase = true;
}
}
maxAscent += extraAscent;
maxDescent += extraDescent;
lineHeight = maxAscent + maxDescent;
aveCharWidth = styles[STYLE_DEFAULT].aveCharWidth;
spaceWidth = styles[STYLE_DEFAULT].spaceWidth;
@ -361,10 +456,10 @@ void ViewStyle::EnsureStyle(size_t index) {
void ViewStyle::ResetDefaultStyle() {
styles[STYLE_DEFAULT].Clear(ColourDesired(0,0,0),
ColourDesired(0xff,0xff,0xff),
Platform::DefaultFontSize(), fontNames.Save(Platform::DefaultFont()),
SC_CHARSET_DEFAULT,
false, false, false, false, Style::caseMixed, true, true, false);
ColourDesired(0xff,0xff,0xff),
Platform::DefaultFontSize(), fontNames.Save(Platform::DefaultFont()),
SC_CHARSET_DEFAULT,
false, false, false, false, Style::caseMixed, true, true, false);
}
void ViewStyle::ClearStyles() {

View File

@ -39,6 +39,20 @@ public:
const char *Save(const char *name);
};
class FontRealised : public FontSpecification, public FontMeasurements {
// Private so FontRealised objects can not be copied
FontRealised(const FontRealised &);
FontRealised &operator=(const FontRealised &);
public:
Font font;
FontRealised *frNext;
FontRealised(const FontSpecification &fs);
virtual ~FontRealised();
void Realise(Surface &surface, int zoomLevel);
FontRealised *Find(const FontSpecification &fs);
void FindMaxAscentDescent(unsigned int &maxAscent, unsigned int &maxDescent);
};
enum IndentView {ivNone, ivReal, ivLookForward, ivLookBoth};
enum WhiteSpaceVisibility {wsInvisible=0, wsVisibleAlways=1, wsVisibleAfterIndent=2};
@ -48,6 +62,7 @@ enum WhiteSpaceVisibility {wsInvisible=0, wsVisibleAlways=1, wsVisibleAfterInden
class ViewStyle {
public:
FontNames fontNames;
FontRealised *frFirst;
size_t stylesSize;
Style *styles;
LineMarker markers[MARKER_MAX + 1];
@ -114,11 +129,16 @@ public:
int marginStyleOffset;
int annotationVisible;
int annotationStyleOffset;
bool braceHighlightIndicatorSet;
int braceHighlightIndicator;
bool braceBadLightIndicatorSet;
int braceBadLightIndicator;
ViewStyle();
ViewStyle(const ViewStyle &source);
~ViewStyle();
void Init(size_t stylesSize_=64);
void CreateFont(const FontSpecification &fs);
void RefreshColourPalette(Palette &pal, bool want);
void Refresh(Surface &surface);
void AllocStyles(size_t sizeNew);

View File

@ -8,6 +8,13 @@
#include <string.h>
#include <stdlib.h>
#ifdef _MSC_VER
#pragma warning(disable: 4786)
#endif
#include <vector>
#include <map>
#include "Platform.h"
#include "XPM.h"
@ -38,6 +45,10 @@ static size_t MeasureLength(const char *s) {
return i;
}
ColourDesired XPM::ColourDesiredFromCode(int ch) const {
return colourCodeTable[ch]->desired;
}
ColourAllocated XPM::ColourFromCode(int ch) const {
return colourCodeTable[ch]->allocated;
#ifdef SLOW
@ -200,6 +211,21 @@ void XPM::Draw(Surface *surface, PRectangle &rc) {
}
}
void XPM::PixelAt(int x, int y, ColourDesired &colour, bool &transparent) const {
if (!data || !codes || !colours || !lines || (x<0) || (x >= width) || (y<0) || (y >= height)) {
colour = 0;
transparent = true;
return;
}
int code = lines[y+nColours+1][x];
transparent = code == codeTransparent;
if (transparent) {
colour = 0;
} else {
colour = ColourDesiredFromCode(code).AsLong();
}
}
const char **XPM::LinesFormFromTextForm(const char *textForm) {
// Build the lines form out of the text form
const char **linesForm = 0;
@ -261,14 +287,14 @@ void XPMSet::Clear() {
width = -1;
}
void XPMSet::Add(int id, const char *textForm) {
void XPMSet::Add(int ident, const char *textForm) {
// Invalidate cached dimensions
height = -1;
width = -1;
// Replace if this id already present
for (int i = 0; i < len; i++) {
if (set[i]->GetId() == id) {
if (set[i]->GetId() == ident) {
set[i]->Init(textForm);
set[i]->CopyDesiredColours();
return;
@ -278,7 +304,7 @@ void XPMSet::Add(int id, const char *textForm) {
// Not present, so add to end
XPM *pxpm = new XPM(textForm);
if (pxpm) {
pxpm->SetId(id);
pxpm->SetId(ident);
pxpm->CopyDesiredColours();
if (len == maximum) {
maximum += 64;
@ -294,9 +320,9 @@ void XPMSet::Add(int id, const char *textForm) {
}
}
XPM *XPMSet::Get(int id) {
XPM *XPMSet::Get(int ident) {
for (int i = 0; i < len; i++) {
if (set[i]->GetId() == id) {
if (set[i]->GetId() == ident) {
return set[i];
}
}
@ -324,3 +350,110 @@ int XPMSet::GetWidth() {
}
return (width > 0) ? width : 0;
}
RGBAImage::RGBAImage(int width_, int height_, const unsigned char *pixels_) :
height(height_), width(width_) {
if (pixels_) {
pixelBytes.assign(pixels_, pixels_ + CountBytes());
} else {
pixelBytes.resize(CountBytes());
}
}
RGBAImage::RGBAImage(const XPM &xpm) {
height = xpm.GetHeight();
width = xpm.GetWidth();
pixelBytes.resize(CountBytes());
for (int y=0; y<height; y++) {
for (int x=0; x<width; x++) {
ColourDesired colour;
bool transparent = false;
xpm.PixelAt(x, y, colour, transparent);
SetPixel(x, y, colour, transparent ? 0 : 255);
}
}
}
RGBAImage::~RGBAImage() {
}
int RGBAImage::CountBytes() const {
return width * height * 4;
}
const unsigned char *RGBAImage::Pixels() const {
return &pixelBytes[0];
}
void RGBAImage::SetPixel(int x, int y, ColourDesired colour, int alpha) {
unsigned char *pixel = &pixelBytes[0] + (y*width+x) * 4;
// RGBA
pixel[0] = colour.GetRed();
pixel[1] = colour.GetGreen();
pixel[2] = colour.GetBlue();
pixel[3] = alpha;
}
RGBAImageSet::RGBAImageSet() : height(-1), width(-1){
}
RGBAImageSet::~RGBAImageSet() {
Clear();
}
/// Remove all images.
void RGBAImageSet::Clear() {
for (ImageMap::iterator it=images.begin(); it != images.end(); ++it) {
delete it->second;
it->second = 0;
}
images.clear();
height = -1;
width = -1;
}
/// Add an image.
void RGBAImageSet::Add(int ident, RGBAImage *image) {
ImageMap::iterator it=images.find(ident);
if (it == images.end()) {
images[ident] = image;
} else {
delete it->second;
it->second = image;
}
height = -1;
width = -1;
}
/// Get image by id.
RGBAImage *RGBAImageSet::Get(int ident) {
ImageMap::iterator it = images.find(ident);
if (it != images.end()) {
return it->second;
}
return NULL;
}
/// Give the largest height of the set.
int RGBAImageSet::GetHeight() const {
if (height < 0) {
for (ImageMap::const_iterator it=images.begin(); it != images.end(); ++it) {
if (height < it->second->GetHeight()) {
height = it->second->GetHeight();
}
}
}
return (height > 0) ? height : 0;
}
/// Give the largest width of the set.
int RGBAImageSet::GetWidth() const {
if (width < 0) {
for (ImageMap::const_iterator it=images.begin(); it != images.end(); ++it) {
if (width < it->second->GetWidth()) {
width = it->second->GetWidth();
}
}
}
return (width > 0) ? width : 0;
}

View File

@ -24,6 +24,7 @@ class XPM {
char codeTransparent;
char *codes;
ColourPair *colours;
ColourDesired ColourDesiredFromCode(int ch) const;
ColourAllocated ColourFromCode(int ch) const;
void FillRun(Surface *surface, int code, int startX, int y, int x);
char **lines;
@ -46,6 +47,7 @@ public:
int GetId() const { return pid; }
int GetHeight() const { return height; }
int GetWidth() const { return width; }
void PixelAt(int x, int y, ColourDesired &colour, bool &transparent) const;
static const char **LinesFormFromTextForm(const char *textForm);
};
@ -64,15 +66,59 @@ public:
/// Remove all XPMs.
void Clear();
/// Add a XPM.
void Add(int id, const char *textForm);
void Add(int ident, const char *textForm);
/// Get XPM by id.
XPM *Get(int id);
XPM *Get(int ident);
/// Give the largest height of the set.
int GetHeight();
/// Give the largest width of the set.
int GetWidth();
};
/**
* An translucent image stoed as a sequence of RGBA bytes.
*/
class RGBAImage {
// Private so RGBAImage objects can not be copied
RGBAImage(const RGBAImage &);
RGBAImage &operator=(const RGBAImage &);
int height;
int width;
std::vector<unsigned char> pixelBytes;
public:
RGBAImage(int width_, int height_, const unsigned char *pixels_);
RGBAImage(const XPM &xpm);
virtual ~RGBAImage();
int GetHeight() const { return height; }
int GetWidth() const { return width; }
int CountBytes() const;
const unsigned char *Pixels() const;
void SetPixel(int x, int y, ColourDesired colour, int alpha=0xff);
};
/**
* A collection of RGBAImage pixmaps indexed by integer id.
*/
class RGBAImageSet {
typedef std::map<int, RGBAImage*> ImageMap;
ImageMap images;
mutable int height; ///< Memorize largest height of the set.
mutable int width; ///< Memorize largest width of the set.
public:
RGBAImageSet();
~RGBAImageSet();
/// Remove all images.
void Clear();
/// Add an image.
void Add(int ident, RGBAImage *image);
/// Get image by id.
RGBAImage *Get(int ident);
/// Give the largest height of the set.
int GetHeight() const;
/// Give the largest width of the set.
int GetWidth() const;
};
#ifdef SCI_NAMESPACE
}
#endif

View File

@ -1 +1 @@
225
229

23
scripts/rstrip-whitespace.py Executable file
View File

@ -0,0 +1,23 @@
#!/usr/bin/env python
import sys
filenames = sys.argv[1:]
def backup_file (fn):
open ("%s~" % fn, "w").write (open (fn, "r").read ())
for fn in filenames:
#backup_file (fn)
contents = open (fn, "r").read ()
lines = contents.split ('\n')
with open (fn, "w") as fobj:
for line in lines:
line = line.rstrip ()
fobj.write ("%s\n" % line)
contents = open (fn, "r").read ()
contents.rstrip ()
while contents[-1] in " \t\r\n":
contents = contents[:-1]
open (fn, "w").write ("%s\n" % contents)

View File

@ -38,7 +38,7 @@
#define INFO "<span size=\"larger\" weight=\"bold\">%s</span>"
#define CODENAME "<span weight=\"bold\">\"" GEANY_CODENAME "\"</span>"
#define BUILDDATE "<span size=\"smaller\">%s</span>"
#define COPYRIGHT "Copyright (c) 2005-2011\nNick Treleaven\nColomban Wendling\nEnrico Tröger\nFrank Lanitz\nAll rights reserved."
#define COPYRIGHT "Copyright (c) 2005-2011\nColomban Wendling\nNick Treleaven\nMatthew Brush\nEnrico Tröger\nFrank Lanitz\nAll rights reserved."
const gchar *translators[][2] = {
{ "ast", "Marcos Costales &lt;marcoscostales@gmail.com&gt;"},
@ -60,8 +60,9 @@ const gchar *translators[][2] = {
{ "ko", "Park Jang-heon &lt;dotkabi@gmail.com&gt;" },
{ "kk", "Baurzhan Muftakhidinov &lt;baurthefirst@gmail.com&gt;"},
{ "lb", "Laurent Hoeltgen &lt;hoeltgman@gmail.com&gt;" },
{ "mn", "tsetsee &lt;tsetsee.yugi@gmail.com&gt;"},
{ "nl", "Peter Scholtens &lt;peter.scholtens@xs4all.nl&gt;\nAyke van Laethem &lt;aykevanlaethem@gmail.com&gt;" },
{ "pl_PL", "Jarosław Foksa &lt;jfoksa@gmail.com&gt;" },
{ "pl", "Wojciech Świderski &lt;woj.swiderski@gmail.com&gt;"},
{ "pt_BR", "Alexandra Moreire &lt;alexandream@gmail.com&gt;\n"
"Adrovane Marques Kade &lt;adrovane@gmail.com&gt;\n"
"Rafael Peregrino da Silva &lt;rperegrino@linuxnewmedia.com.br&gt;"},
@ -79,7 +80,7 @@ static const gint translators_len = G_N_ELEMENTS(translators);
const gchar *prev_translators[][2] = {
{ "es", "Damián Viano &lt;debian@damianv.com.ar&gt;\nNacho Cabanes &lt;ncabanes@gmail.com&gt;" },
{ "pl_PL", "Jacek Wolszczak &lt;shutdownrunner@o2.pl&gt;" },
{ "pl", "Jacek Wolszczak &lt;shutdownrunner@o2.pl&gt;\nJarosław Foksa &lt;jfoksa@gmail.com&gt;" },
{ "nl", "Kurt De Bree &lt;kdebree@telenet.be&gt;" }
};
static const gint prev_translators_len = G_N_ELEMENTS(prev_translators);

View File

@ -1270,9 +1270,6 @@ static void on_build_menu_item(GtkWidget *w, gpointer user_data)
if (doc && doc->changed)
{
if (document_need_save_as(doc) && !dialogs_show_save_as())
return;
if (!document_save_file(doc, FALSE))
return;
}
@ -1393,7 +1390,7 @@ static void create_build_menu_item(GtkWidget *menu, GeanyKeyGroup *group, GtkAcc
}
gtk_widget_show(item);
if (bs->key_binding >= 0)
add_menu_accel(group, bs->key_binding, ag, item);
add_menu_accel(group, (guint) bs->key_binding, ag, item);
gtk_container_add(GTK_CONTAINER(menu), item);
if (bs->cb != NULL)
{
@ -1627,21 +1624,21 @@ static void set_stop_button(gboolean stop)
if (run_button != NULL)
button_stock_id = gtk_tool_button_get_stock_id(run_button);
if (stop && utils_str_equal(button_stock_id, "gtk-stop"))
if (stop && utils_str_equal(button_stock_id, GTK_STOCK_STOP))
return;
if (! stop && utils_str_equal(button_stock_id, "gtk-execute"))
if (! stop && utils_str_equal(button_stock_id, GTK_STOCK_EXECUTE))
return;
/* use the run button also as stop button */
if (stop)
{
if (run_button != NULL)
gtk_tool_button_set_stock_id(run_button, "gtk-stop");
gtk_tool_button_set_stock_id(run_button, GTK_STOCK_STOP);
}
else
{
if (run_button != NULL)
gtk_tool_button_set_stock_id(run_button, "gtk-execute");
gtk_tool_button_set_stock_id(run_button, GTK_STOCK_EXECUTE);
}
}
@ -2307,7 +2304,8 @@ static const gchar *fixedkey="xx_xx_xx";
static void build_load_menu_grp(GKeyFile *config, GeanyBuildCommand **dst, gint grp,
gchar *prefix, gboolean loc)
{
gint cmd, prefixlen; /* NOTE prefixlen used in macros above */
gint cmd;
gsize prefixlen; /* NOTE prefixlen used in macros above */
GeanyBuildCommand *dstcmd;
gchar *key;
static gchar cmdbuf[3] = " ";
@ -2518,7 +2516,8 @@ void build_load_menu(GKeyFile *config, GeanyBuildSource src, gpointer p)
static gint build_save_menu_grp(GKeyFile *config, GeanyBuildCommand *src, gint grp, gchar *prefix)
{
gint cmd, prefixlen; /* NOTE prefixlen used in macros above */
gint cmd;
gsize prefixlen; /* NOTE prefixlen used in macros above */
gchar *key;
gint count = 0;
enum GeanyBuildCmdEntries i;
@ -2767,5 +2766,3 @@ void build_init(void)
/* set the submenu to the toolbar item */
geany_menu_button_action_set_menu(GEANY_MENU_BUTTON_ACTION(widgets.build_action), toolmenu);
}

Some files were not shown because too many files have changed in this diff Show More