Branch: refs/heads/master
Author: Jiřà Techet <techet(a)gmail.com>
Committer: GitHub <noreply(a)github.com>
Date: Sun, 26 Jan 2025 21:10:53 UTC
Commit: 7ec34de3badeecafe459276bfd01465a849e058c
https://github.com/geany/geany-plugins/commit/7ec34de3badeecafe459276bfd014…
Log Message:
-----------
Merge pull request #1331 from techee/lsp
Add LSP plugin
Modified Paths:
--------------
MAINTAINERS
Makefile.am
README
build/geany-plugins.nsi
build/lsp.m4
configure.ac
lsp/AUTHORS
lsp/COPYING
lsp/ChangeLog
lsp/Makefile.am
lsp/NEWS
lsp/README
lsp/data/Makefile.am
lsp/data/lsp.conf
lsp/deps/Makefile.am
lsp/deps/json-glib/json-array.c
lsp/deps/json-glib/json-builder.c
lsp/deps/json-glib/json-builder.h
lsp/deps/json-glib/json-debug.c
lsp/deps/json-glib/json-debug.h
lsp/deps/json-glib/json-enum-types.c
lsp/deps/json-glib/json-enum-types.h
lsp/deps/json-glib/json-gboxed.c
lsp/deps/json-glib/json-generator.c
lsp/deps/json-glib/json-generator.h
lsp/deps/json-glib/json-glib.h
lsp/deps/json-glib/json-gobject-private.h
lsp/deps/json-glib/json-gobject.c
lsp/deps/json-glib/json-gobject.h
lsp/deps/json-glib/json-gvariant.c
lsp/deps/json-glib/json-gvariant.h
lsp/deps/json-glib/json-node.c
lsp/deps/json-glib/json-object.c
lsp/deps/json-glib/json-parser.c
lsp/deps/json-glib/json-parser.h
lsp/deps/json-glib/json-path.c
lsp/deps/json-glib/json-path.h
lsp/deps/json-glib/json-reader.c
lsp/deps/json-glib/json-reader.h
lsp/deps/json-glib/json-scanner.c
lsp/deps/json-glib/json-scanner.h
lsp/deps/json-glib/json-serializable.c
lsp/deps/json-glib/json-types-private.h
lsp/deps/json-glib/json-types.h
lsp/deps/json-glib/json-utils.c
lsp/deps/json-glib/json-utils.h
lsp/deps/json-glib/json-value.c
lsp/deps/json-glib/json-version-macros.h
lsp/deps/json-glib/json-version.h
lsp/deps/jsonrpc-glib/jsonrpc-client.c
lsp/deps/jsonrpc-glib/jsonrpc-client.h
lsp/deps/jsonrpc-glib/jsonrpc-glib.h
lsp/deps/jsonrpc-glib/jsonrpc-input-stream-private.h
lsp/deps/jsonrpc-glib/jsonrpc-input-stream.c
lsp/deps/jsonrpc-glib/jsonrpc-input-stream.h
lsp/deps/jsonrpc-glib/jsonrpc-marshalers.c
lsp/deps/jsonrpc-glib/jsonrpc-marshalers.h
lsp/deps/jsonrpc-glib/jsonrpc-message.c
lsp/deps/jsonrpc-glib/jsonrpc-message.h
lsp/deps/jsonrpc-glib/jsonrpc-output-stream.c
lsp/deps/jsonrpc-glib/jsonrpc-output-stream.h
lsp/deps/jsonrpc-glib/jsonrpc-server.c
lsp/deps/jsonrpc-glib/jsonrpc-server.h
lsp/deps/jsonrpc-glib/jsonrpc-version-macros.h
lsp/deps/jsonrpc-glib/jsonrpc-version.h
lsp/src/Makefile.am
lsp/src/lsp-autocomplete.c
lsp/src/lsp-autocomplete.h
lsp/src/lsp-code-lens.c
lsp/src/lsp-code-lens.h
lsp/src/lsp-command.c
lsp/src/lsp-command.h
lsp/src/lsp-diagnostics.c
lsp/src/lsp-diagnostics.h
lsp/src/lsp-extension.c
lsp/src/lsp-extension.h
lsp/src/lsp-format.c
lsp/src/lsp-format.h
lsp/src/lsp-goto-anywhere.c
lsp/src/lsp-goto-anywhere.h
lsp/src/lsp-goto-panel.c
lsp/src/lsp-goto-panel.h
lsp/src/lsp-goto.c
lsp/src/lsp-goto.h
lsp/src/lsp-highlight.c
lsp/src/lsp-highlight.h
lsp/src/lsp-hover.c
lsp/src/lsp-hover.h
lsp/src/lsp-log.c
lsp/src/lsp-log.h
lsp/src/lsp-main.c
lsp/src/lsp-progress.c
lsp/src/lsp-progress.h
lsp/src/lsp-rename.c
lsp/src/lsp-rename.h
lsp/src/lsp-rpc.c
lsp/src/lsp-rpc.h
lsp/src/lsp-selection-range.c
lsp/src/lsp-selection-range.h
lsp/src/lsp-semtokens.c
lsp/src/lsp-semtokens.h
lsp/src/lsp-server.c
lsp/src/lsp-server.h
lsp/src/lsp-signature.c
lsp/src/lsp-signature.h
lsp/src/lsp-symbol-kinds.c
lsp/src/lsp-symbol-kinds.h
lsp/src/lsp-symbol-tree.c
lsp/src/lsp-symbol-tree.h
lsp/src/lsp-symbol.c
lsp/src/lsp-symbol.h
lsp/src/lsp-symbols.c
lsp/src/lsp-symbols.h
lsp/src/lsp-sync.c
lsp/src/lsp-sync.h
lsp/src/lsp-utils.c
lsp/src/lsp-utils.h
lsp/src/lsp-workspace-folders.c
lsp/src/lsp-workspace-folders.h
lsp/src/spawn/lspunixinputstream.c
lsp/src/spawn/lspunixinputstream.h
lsp/src/spawn/lspunixoutputstream.c
lsp/src/spawn/lspunixoutputstream.h
lsp/src/spawn/spawn.c
lsp/src/spawn/spawn.h
po/POTFILES.in
po/POTFILES.skip
Modified: MAINTAINERS
7 lines changed, 7 insertions(+), 0 deletions(-)
===================================================================
@@ -194,6 +194,13 @@ M: Frank Lanitz <frank(a)frank.uvena.de>
W: http://plugins.geany.org/lipsum.html
S: Maintained
+lsp
+P: Jiřà Techet <techet(a)gmail.com>
+g: @techee
+M: Jiřà Techet <techet(a)gmail.com>
+W: http://plugins.geany.org/lsp.html
+S: Maintained
+
markdown
P: Matthew Brush <matt(a)geany.org>
g: @codebrainz
Modified: Makefile.am
4 lines changed, 4 insertions(+), 0 deletions(-)
===================================================================
@@ -109,6 +109,10 @@ if ENABLE_LIPSUM
SUBDIRS += lipsum
endif
+if ENABLE_LSP
+SUBDIRS += lsp
+endif
+
if ENABLE_MARKDOWN
SUBDIRS += markdown
endif
Modified: README
1 lines changed, 1 insertions(+), 0 deletions(-)
===================================================================
@@ -71,6 +71,7 @@ Available plugins are:
* ``latex`` -- the LaTeX plugin
* ``lineoperations`` -- simple line functions that can be applied to an open file
* ``lipsum`` -- the Lipsum plugin
+* ``lsp`` -- the LSP plugin
* ``markdown`` -- the Markdown plugin
* ``overview``-- the overview plugin
* ``pairtaghighlighter`` -- the PairTagHighlighter plugin
Modified: build/geany-plugins.nsi
1 lines changed, 1 insertions(+), 0 deletions(-)
===================================================================
@@ -198,6 +198,7 @@ Section Uninstall
Delete "$INSTDIR\lib\geany\keyrecord.dll"
Delete "$INSTDIR\lib\geany\lipsum.dll"
Delete "$INSTDIR\lib\geany\lineoperations.dll"
+ Delete "$INSTDIR\lib\geany\lsp.dll"
Delete "$INSTDIR\lib\geany\overview.dll"
Delete "$INSTDIR\lib\geany\pairtaghighlighter.dll"
Delete "$INSTDIR\lib\geany\pohelper.dll"
Modified: build/lsp.m4
39 lines changed, 39 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,39 @@
+AC_DEFUN([GP_CHECK_LSP],
+[
+ GP_ARG_DISABLE([LSP], [auto])
+
+ JSON_GLIB_PACKAGE_NAME=json-glib-1.0
+ JSON_GLIB_VERSION=1.10
+ JSONRPC_GLIB_PACKAGE_NAME=jsonrpc-glib-1.0
+ JSONRPC_GLIB_VERSION=3.44
+
+ AC_ARG_ENABLE(system-jsonrpc,
+ AC_HELP_STRING([--enable-system-jsonrpc],
+ [Force using system json-glib and jsonrpc-glib libraries for the LSP plugin. [[default=no]]]),,
+ enable_system_jsonrpc=no)
+
+ PKG_CHECK_MODULES([SYSTEM_JSONRPC],
+ [${JSON_GLIB_PACKAGE_NAME} >= ${JSON_GLIB_VERSION}
+ ${JSONRPC_GLIB_PACKAGE_NAME} >= ${JSONRPC_GLIB_VERSION}],
+ have_system_jsonrpc=yes
+ echo "Required system versions of json-glib and jsonrpc-glib found - using them.",
+ have_system_jsonrpc=no
+ echo "Required system versions of json-glib and jsonrpc-glib not found - using builtin versions.")
+
+ AS_IF([test x"$enable_system_jsonrpc" = "xyes" || test x"$have_system_jsonrpc" = "xyes"],
+ [GP_CHECK_PLUGIN_DEPS([LSP], [LSP],
+ [${JSON_GLIB_PACKAGE_NAME} >= ${JSON_GLIB_VERSION}
+ ${JSONRPC_GLIB_PACKAGE_NAME} >= ${JSONRPC_GLIB_VERSION}])],
+ [])
+
+ AM_CONDITIONAL(ENABLE_BUILTIN_JSONRPC, [ test x"$have_system_jsonrpc" = "xno" ])
+
+ GP_COMMIT_PLUGIN_STATUS([LSP])
+
+ AC_CONFIG_FILES([
+ lsp/Makefile
+ lsp/deps/Makefile
+ lsp/src/Makefile
+ lsp/data/Makefile
+ ])
+])
Modified: configure.ac
1 lines changed, 1 insertions(+), 0 deletions(-)
===================================================================
@@ -55,6 +55,7 @@ GP_CHECK_GITCHANGEBAR
GP_CHECK_KEYRECORD
GP_CHECK_LINEOPERATIONS
GP_CHECK_LIPSUM
+GP_CHECK_LSP
GP_CHECK_MARKDOWN
GP_CHECK_OVERVIEW
GP_CHECK_PAIRTAGHIGHLIGHTER
Modified: lsp/AUTHORS
1 lines changed, 1 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1 @@
+Jiřà Techet <techet(a)gmail.com>
Modified: lsp/COPYING
340 lines changed, 340 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
Modified: lsp/ChangeLog
0 lines changed, 0 insertions(+), 0 deletions(-)
===================================================================
No diff available, check online
Modified: lsp/Makefile.am
4 lines changed, 4 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,4 @@
+include $(top_srcdir)/build/vars.auxfiles.mk
+
+SUBDIRS = deps src data
+plugin = lsp
Modified: lsp/NEWS
0 lines changed, 0 insertions(+), 0 deletions(-)
===================================================================
No diff available, check online
Modified: lsp/README
288 lines changed, 288 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,288 @@
+===
+LSP
+===
+
+.. contents::
+
+About
+=====
+
+LSP Client is a language server protocol client plugin that allows to run multiple
+language servers for various programming languages, making their functionality
+accessible to Geany.
+
+Configuration
+=============
+
+The plugin does not come bundled with any language server; these must
+be installed independently of the plugin. For installation and configuration
+instructions, please refer to the documentation of the specific servers you plan
+to use, as some may have specific requirements. Note that many language servers,
+such as ``clangd``, ``pylsp``, and ``gopls``, are often packaged by Linux
+distributions, making them easy to install and use.
+
+You can configure servers and other settings using the User configuration file,
+accessible from::
+
+ Tools->LSP Client->User configuration
+
+This file provides extensive information about all the settings options, so be
+sure to refer to it for more details. The default configuration file comes with
+pre-configured values for several language servers; other servers have to be
+added manually.
+
+By default, the LSP plugin is disabled unless explicitly enabled for a
+project under
+
+::
+
+ Project->Properties->LSP Client
+
+This behavior can be controlled by the first three configuration options in
+the ``[all]`` section of the configuration file.
+
+Language servers are started lazily, meaning they only launch when you switch
+a tab to a file with a filetype that has a corresponding LSP server configured.
+After the initial handshake between the client and server, you can check the
+result under
+
+::
+
+ Tools->LSP Client->Server Initialize Responses
+
+This file also provides information about the capabilities offered by the server;
+for more details, refer to:
+
+https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/
+
+In addition to the User configuration file, you can also create a per-project
+configuration file (which can also be shared by multiple projects). This file
+can be configured under the
+
+::
+
+ Project->Properties->LSP Client
+
+tab.
+
+Furthermore, the plugin offers a range of customizable keybindings, which can be
+configured from::
+
+ Edit->Preferences->Keybindings->LSP Client
+
+Usage
+=====
+
+This section provides an overview of the individual LSP features supported by
+the plugin, along with guidance on how to use them. You can enable or disable
+each feature in the configuration file, where you can also customize certain
+aspects of their behavior.
+
+Please note that not all language servers support every feature. For more
+information on the specific features supported by a language server, consult
+the server's documentation.
+
+Autocompletion
+--------------
+
+Autocompletion works similarly to Geany's autocompletion feature. You can
+configure keybindings triggering the autocompletion popup.
+
+Function signagure
+------------------
+
+When you type an open brace after a function name, the plugin displays the
+function's signature in a popup window similarly to Geany's behavior.
+
+Diagnostic messages
+-------------------
+
+LSP diagnostic messages typically include error messages or warnings from
+compilers, as well as messages from linters. These messages are highlighted in
+the code; the exact style of highlighting can be configured to suit your
+preferences. When you hover over the highlighted part with your mouse cursor,
+a popup window appears, providing additional details about the issue. It is
+also possible to display all diagnostic messages received from the server in
+the message window.
+
+Code actions
+------------
+
+Some servers offer auto-fixes of certain issues or various refactoring options.
+For instance, the ``clangd`` server displays ``fix available`` next to the issue
+in the hover popup window. To perform the auto-fix, right-click the line with
+the issue and select the corresponding option from the Commands submenu. This
+popup can also be invoked by a keybinding.
+
+Code lenses
+-----------
+
+Code lenses are executable commands that are specific to a particular piece of
+code. As Geany's Scintilla component limitations prevent these commands
+from being clickable and executable directly in the editor, they are accessible
+through the Commands submenu of the context menu, similarly to code actions.
+
+Semantic token type highlighting
+--------------------------------
+
+Language servers that provide semantic token support can be used to highlight
+types, such as class names, in the code. You can customize various aspects of
+how the results are visualized in the editor through the configuration file.
+
+Hover popup
+-----------
+
+The language server can be configured to display a popup window with detailed
+information about the symbol under the mouse cursor. However, as this feature
+can be slightly annoying, it is disabled by default. Alternatively, you can
+access this feature through a keybinding.
+
+Symbol tree
+-----------
+
+The LSP symbol tree tab in the sidebar, separate from Geany's Symbols tab,
+shows document symbols in a similar manner to the Geany's symbol tree feature.
+
+Go to symbol definition/declaration
+-----------------------------------
+
+Similarly to Geany, you can navigate to the symbol definition/declaration
+by control-clicking it in the document or by using the corresponding keybinding.
+This feature is also available from the context menu.
+
+Go to type definition
+---------------------
+
+This feature enables quick navigation to the definition of the type associated
+with the symbol under the cursor, such as the type of a variable. You can also
+access this feature from the context menu.
+
+Swap header/source
+------------------
+
+This is a non-standard clangd extension allowing quick swapping between a
+source file and the corresponding header. This feature is not supported by
+any other language server.
+
+Find references
+---------------
+
+This feature finds all references of the symbol under the cursor in the project.
+This feature is also accessible from the context menu.
+
+Find implementations
+--------------------
+
+This feature allows you to locate all classes that implement the interface under
+the cursor.
+
+Navigation to document/project symbols, files, and line numbers
+---------------------------------------------------------------
+
+The plugin provides a simple, VSCode-style panel for navigating your project.
+The
+
+::
+
+ Tools->LSP Client->Go to Anywhere
+
+command offers four types of navigation options:
+
+- Open files by typing their name directly in the entry
+- Navigate to symbols in the current document by prefixing the query with ``@``
+- Navigate to symbols across the entire project by prefixing the query with ``#``
+- Jump to a specific line in the current document by prefixing the query with ``:``
+
+The other related queries in the LSP Client menu (also accessible via a keybinding)
+simply pre-fill the prefix for you, but otherwise function identically.
+
+Code formatting
+---------------
+
+The code formatting feature allows you to format either the entire document or
+a selected portion of code, depending on the LSP server's support for this
+functionality. You can access this feature from the context menu.
+
+Identical symbol highlighting
+-----------------------------
+
+When you click on a symbol in the document, this feature highlights all its
+occurrences in the document. You can customize the highlighting style to your
+preference by configuring it in the configuration file. Also, it is possible
+to disable this feature to be performed automatically, but, instead, manually
+through a keybinding.
+
+Smart selection expanding/shrinking
+-----------------------------------
+
+This feature allows to expand the current text selection to contain the next
+upper syntactic element such as a parent block in programming languages or a
+parent tag in XML. Selection shrinking works in the opposite direction.
+
+Document symbol renaming
+------------------------
+
+This feature leverages the identical symbol highlighting described above to
+select all symbol occurrences, create multiple cursors at their positions in the
+document, and rename them simultaneously as you type. You can also access this
+feature from the context menu.
+
+Project-wide renaming
+---------------------
+
+After selecting Rename in Project from the context menu or the plugin menu,
+you can rename all symbols in the project.
+
+**Warning:** This feature has a potential to modify many files and language
+servers may not be completely reliable when performing the rename so be very
+cautious when using it. The plugin does not perform any additional
+checks and does not show any preview of the changes so it is best to use this
+feature only after committing all modified files so you can
+easily revert to a working state if needed. Since this is potentially a
+dangerous operation, to prevent accidental renames, the "Rename" button in the
+dialog is not selected by defalut and simply pressing enter just cancels the
+dialog.
+
+Limitations
+===========
+
+By design, the plugin communicates over stdin/stdout only, is responsible
+for launching and terminating the language server process, and supports only
+a single language server per file type.
+
+All of these limitations are addressed by the LSP proxy project available at
+https://github.com/techee/lsp-proxy and related issues should be directed there.
+
+License
+=======
+
+Geany LSP Client is distributed under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version. A copy of this license
+can be found in the file COPYING included with the source code of this
+program.
+
+Downloads
+=========
+
+Geany LSP Client can be downloaded from the development repository available
+at https://github.com/techee/geany-lsp/. In addition, it is also distributed
+as part of the combined Geany Plugins release. For more information and
+downloads, please visit https://plugins.geany.org/geany-plugins/
+
+Development Code
+================
+
+Get the code from::
+
+ git clone https://github.com/techee/geany-lsp.git
+
+Ideas, questions, patches and bug reports
+=========================================
+
+Please direct all questions, bug reports and patches to the development
+repository at https://github.com/techee/geany-lsp/ and open the corresponding
+bug report or pull request there.
+
+2023-2024 by Jiřà Techet
+techet(at)gmail(dot)com
Modified: lsp/data/Makefile.am
5 lines changed, 5 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,5 @@
+include $(top_srcdir)/build/vars.docs.mk
+
+plugin = lsp
+
+dist_plugindata_DATA = lsp.conf
Modified: lsp/data/lsp.conf
534 lines changed, 534 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,534 @@
+# The global configuration file, accessible through
+# Tools->LSP Client->Global Configuration, defines default values for various
+# configuration options.
+#
+# When accessing the user configuration file using
+# Tools->LSP Client->User Configuration, a copy of the global configuration file
+# is created in user's configuration directory in which users can override
+# various settings from the global configuration file.
+#
+# In addition, it is possible to create a project-wide configuration file used
+# for a single project or shared by multiple projects whose path can be
+# specified under Project->Properties->LSP Client->Configuration file. When such
+# a file is defined and the project is configured to use the project
+# configuration, this configuration file overrides the global configuration
+# instead of the user configuration file.
+#
+# Each configuration file may contain the [all] section which contains settings
+# common for all language servers, and several filetype-specific sections
+# containing settings specific for the given filetype. The names of these
+# sections are identical to the names defined in
+# Tools->Configuration Files->filetype_extensions.conf; for instance [Python]
+# for the Python programming language (case sensitive). Most of the options can
+# appear both in the [all] section and the filetype-specific sections except for
+# a few that make only sense in the filetype-specific section, like e.g. the
+# 'cmd' option containing the command that starts the server. Any option defined
+# in the filetype-specific section overrides identically named option defined in
+# the [all] section for that particular language server.
+#
+# Not all LSP features are supported by all LSP servers. To learn more about
+# what features are supported by the particular server you are trying to use,
+# you can check the result of the initial client-server handshake by going to
+# Tools->LSP Client->Server Initialize Responses (the server must be running
+# to see any result).
+#
+# All servers are automatically restarted when any of the configuration files
+# changes. Servers are started lazily after a tab is switched to a document for
+# which a server is configured (this means that restart typically means shutdown
+# of all servers after which they are started as needed).
+
+
+[all]
+# Defines whether the plugin should be enabled automatically for new or existing
+# projects (that have not yet been configured to use LSP). This option
+# is only valid in the [all] section
+enable_by_default=false
+# Defines whether the server should be used when no project is open. Servers
+# may not work correctly without a project because most of them need to know
+# the path to the project directory which corresponds to the path defined under
+# Project->Properties->Base path. This option can be partially overridden
+# by project_root_marker_patterns, see below
+use_without_project=false
+# Defines whether the server should be used for files whose path is not within
+# the project directory. This option can be partially overridden by
+# project_root_marker_patterns, see below
+use_outside_project_dir=false
+# A semicolon-separated list of glob patterns of files that are typically stored
+# inside the root directory of the project. Language servers supporting
+# changeNotifications of workspaceFolders (these two values should appear inside
+# the server initialize response) can use these marker files to detect root
+# project directories of open files. Starting from the open file directory,
+# the plugin goes up in the directory structure and tests whether a file
+# matching project_root_marker_patterns exists - if it does, such a directory
+# is considered to be the root directory of the project. This allows to
+# detect projects without any Geany project open and allows the plugin to work
+# on multiple projects simultaneously. Typically, the pattern contains
+# files/directories such as .git, configure.ac, go.mod, etc. If a pattern is
+# found, use_without_project and use_outside_project_dir are ignored
+project_root_marker_patterns=
+# In additon to standard identifier characters a-zA-Z0-9_, this configuration
+# option allows adding extra characters that can appear inside identifiers.
+# For instance $- will add '$' and '-' to the above set.
+extra_identifier_characters=
+# Some servers require that the initialization options configuration is sent
+# using workspace/didChangeConfiguration instead of the initialize request.
+# This option does this right after the initialize request completes.
+send_did_change_configuration=false
+
+# The number of keybindings that can be assigned to LSP code action commands.
+# This option is valid only within the [all] section and changing the value
+# requires either the plugin reload or Geany restart
+command_keybinding_num=5
+# When the keybinding Command 1 is invoked, it checks whether the
+# command_1_regex matches any of the items from the Commands submenu of the
+# context menu. The first matched entry is executed. For convenience, regex
+# matches are case insensitive. Up to command_keybinding_num command keybindings
+# can be specified this way
+command_1_regex=
+# Regex specifying which of the commands present in the context menu under the
+# Commands submenu will be automatically performed on save. If multiple entries
+# match, all of them will be performed. For convenience, regex matches are case
+# insensitive
+command_on_save_regex=
+
+# When the filetype-specific 'rpc_log' settings is defined, this option
+# specifies whether the log should contain all details including method
+# parameters, or just the method name and type of the communication
+rpc_log_full=false
+# Show server's stderr in Geany's stderr (when started from terminal)
+show_server_stderr=false
+# Tracing level of the server (when supported). When enabled, tracing messages
+# are logged into stdout. Valid values are 'off', 'messages', 'verbose'
+trace_value=off
+# Enables or disables telemetry notification logging to stdout
+telemetry_notifications=false
+
+# Whether LSP should be used for autocompletion
+autocomplete_enable=true
+# Servers return the label that can be shown in the autocompletion popup for
+# individual autocompletion entries, or it is possible to use just the text that
+# gets inserted when selecting the entry. See also autocomplete_use_snippets.
+autocomplete_use_label=true
+# Whether snippets should be shown in the autocompletion list. Snippet support
+# is only partial so things may not work as expected. When snippets are enabled,
+# it is recommended to use autocomplete_use_label=true, otherwise snippet
+# tab stops and other snippet information is shown in the autocompletion popup.
+autocomplete_use_snippets=false
+# Maximum number of autocompletion entries shown in the popup window (including
+# those that will only get visible after scrolling the contents)
+autocomplete_window_max_entries=20
+# Maximum number of autocompletion entries shown without scrolling (defining the
+# actual height of the popup)
+autocomplete_window_max_displayed=8
+# The maximum width of the autocompletion popup in displayed characters
+autocomplete_window_max_width=60
+# Whether to automatically apply additional edits defined for the autocompletion
+# entry. These are typically imports of the modules where the inserted symbol is
+# defined
+autocomplete_apply_additional_edits=false
+# Semicolon separated list of character sequences which can trigger
+# autocompletion. Normally, the server defines these but this option can be used
+# to further restrict the list only to some sequences if the server-provided
+# value does not work well (e.g. when server's trigger chars for autocompletion
+# clash with signature trigger chars - Rust server for instance uses '(' for
+# both and omitting '(' in autocomplete sequences shows signature instead)
+autocomplete_trigger_sequences=
+# Semicolon separated list of words that make the autocompletion popup hide.
+# This is useful for instance for languages like Pascal that use keywords
+# 'begin' and 'end' which are typically followed by a newline where typing enter
+# after these words might select some unwanted word from the autocompletion list.
+autocomplete_hide_after_words=
+# Whether to perform autocompletion inside strings
+autocomplete_in_strings=false
+# Show documentation (if available) of selected item in autocompletion popup
+# in Geany status bar
+autocomplete_show_documentation=true
+
+# Whether LSP should be used to display diagnostic messages. Typically these are
+# compiler errors or warnings
+diagnostics_enable=true
+# Semicolon-separated glob patterns specifying files for which diagnostic
+# messages are not shown. Useful when the server has a problem with some files
+diagnostics_disable_for=
+# For the statusbar issue number indicator, consider only issues of the
+# configured severity or highler. Valid values are: 1 (error), 2 (warning),
+# 3 (info), 4 (hint). E.g. setting this value to 2 will show issue number
+# for errors and warnings only.
+diagnostics_statusbar_severity=2
+# Defines the style of error diagnostics - visual style such as underline, and
+# its color. Empty value means that diagnostic messages of the given severity
+# are not displayed.
+# The first number is the "indicator index" of Scintilla - each style should
+# have a unique value from 8 to 31. Can be changed when the value clashes with
+# some other plugin.
+# The remaining values correspond to
+# SCI_INDICSETFORE; SCI_INDICSETALPHA; SCI_INDICSETOUTLINEALPHA; SCI_INDICSETSTYLE
+# - see Scintilla documentation for more information
+diagnostics_error_style=13;#ff3030;70;255;1
+# Defines the style of warning diagnostics
+diagnostics_warning_style=14;#ee00ee;70;255;1
+# Defines the style of information diagnostics
+diagnostics_info_style=15;#909090;70;255;14
+# Defines the style of hint diagnostics
+diagnostics_hint_style=16;#909090;70;255;14
+
+# Whether LSP should be used to show a popup with details when hovering over
+# symbols.
+hover_enable=false
+# Maximum number of lines of the popup window
+hover_popup_max_lines=20
+# Maximum number of paragraphs shown in the popup window
+hover_popup_max_paragraphs=1000
+
+# Whether LSP should be used to show function parameter signatures e.g. after
+# typing '('
+signature_enable=true
+
+# Whether LSP should be used for going to symbol definition/declaration
+goto_enable=true
+
+# Whether LSP should be used for displaying symbols in the sidebar (in a tab
+# separate from normal Geany symbols)
+document_symbols_enable=true
+# The label used for the LSP symbols tab. When left empty, the tab is not
+# displayed. This option is only valid in the [all] section
+document_symbols_tab_label=LSP Symbols
+
+# Whether LSP should be used for highlighting semantic tokens in the editor,
+# such as types. Most servers don't support this feature so disabled by default.
+semantic_tokens_enable=false
+# Always perform "full" semantic token request instead of using "delta"
+# requests. Can be used when servers don't support delta tokens correctly
+semantic_tokens_force_full=false
+# Semicolon-separated list of semantic tokens that should be highlighted as
+# types. For valid values, see
+# https://microsoft.github.io/language-server-protocol/specifications/lsp/3.1…
+semantic_tokens_types=type;class;enum;interface;struct
+# When not empty, Scintilla indicators are used for highlighting semantic
+# token types. See diagnostics_error_style for more details about the valid
+# values. Note that because of Scintilla limitations, this value cannot be bold
+#semantic_tokens_type_style=17;#00007f;255;255;17
+semantic_tokens_type_style=
+# When not using semantic_tokens_type_style, this indicates the index in the
+# Scintilla lexer used for custom keywords. This feature is supported only by
+# some lexers like C/C++ and derived lexers. When using this method, the
+# value can be bold but all the occurrences of the given word in the document
+# is highlighted regardless of the context in which it is used
+semantic_tokens_lexer_kw_index=3
+
+# Whether LSP should be used for highlighting all other uses of a variable under
+# cursor.
+highlighting_enable=true
+# Indicator style used for highlighting - see diagnostics_error_style
+highlighting_style=18;#b0b0b0;90;255;8
+
+# Whether LSP should be used for "code lenses" showing commands available
+# for the given line. After right-clicking the line with the code lens, these
+# commands are available in the Commands submenu.
+code_lens_enable=true
+# Defines the foreground and the background color of the code lens indicator.
+code_lens_style=#000000;#ffffa0
+
+# JSON file containing formatting options defined in
+# https://microsoft.github.io/language-server-protocol/specifications/lsp/3.1…
+# e.g. { "tabSize": 4, "insertSpaces": false }. Supported only by some language
+# servers.
+#formatting_options_file=/home/some_user/my_formatting_config_file.json
+formatting_options_file=
+# Like above but with the JSON placed directly into the value. When both
+# formatting_options_file and formatting_options are specified, the JSON from
+# formatting_options_file is used
+formatting_options={ "tabSize": 4, "insertSpaces": false }
+# Defines whether the LSP code-formatting feature should be auto-performed
+# on every save
+format_on_save=false
+
+# Show progress bar for work in progress server operations. Can be disabled
+# when servers do not correctly terminate progress notifications.
+progress_bar_enable=true
+
+# Enable non-standard clangd extension allowing to swap between C/C++ headers
+# and sources. Only usable for clangd, it does not work with other servers.
+swap_header_source_enable=false
+
+
+# This is a dummy language server configuration describing the available
+# language-specific options. Most of the configuration options from the [all]
+# section can be used here as well.
+# For an extensive list of various servers and their configurations, check
+# https://github.com/neovim/nvim-lspconfig/blob/master/doc/configs.md
+# While the configuration options names of neovim differ from Geany, the
+# general concepts are similar and applicable here.
+[DummyLanguage]
+# The command (including parameters and possibly also the full path) used to
+# start the LSP server. Instead of starting a new server, it is also possible to
+# reuse other language's server using the 'use' option - see the C++
+# configuration
+cmd=srvcmd
+# The server can be started with additional environment variables (such as foo
+# with the value bar, and foo1 with the value bar1 like in the example below).
+env=foo=bar;foo1=bar1
+# File containing initialization options of the server. The server is
+# automatically restarted when this file is modified from within Geany
+initialization_options_file=/home/some_user/init_options.json
+# Like above but with the JSON placed directly into the value. When both
+# initialization_options_file and formatting_options are specified, the JSON
+# from initialization_options_file is used
+initialization_options={"compilationDatabasePath": "/home/some_user/"}
+# When defined, performs logging to the specified file where all RPC
+# communication between the client plugin and the server will be stored (can
+# also be 'stdout' or 'stderr')
+rpc_log=stdout
+# Additional files and their mappings to LSP language IDs for which the server
+# is used as well. The Nth item in the list is always a LSP language ID and the
+# (N+1)th item is a glob pattern defining files for which the language ID is
+# used
+lang_id_mappings=dummylanguage;*.dummy
+
+
+[C]
+# By default, clangd expects compile_commands.json inside the 'build' directory
+# of your project. You can create it using either 'meson setup build' if your
+# project uses meson or e.g. using:
+# mkdir build; bear --output build/compile_commands.json -- make
+# if your project uses some other build tool (you need to install the bear tool
+# first). The compile_commands.json file has to be manually regenerated when
+# the build is modified in any way, such as a file is added/removed.
+cmd=clangd
+swap_header_source_enable=true
+autocomplete_in_strings=true
+autocomplete_use_label=false
+semantic_tokens_enable=true
+#initialization_options={"compilationDatabasePath": "/home/some_user/my_project/my_builddir"}
+formatting_options={ "tabSize": 4, "insertSpaces": false }
+command_1_regex=Apply fix:.*
+#rpc_log=stdout
+#rpc_log_full=true
+#show_server_stderr=true
+
+
+[C++]
+# Don't start a new server but reuse the server defined for some other language
+# instead (C server used for C++ in this case)
+use=C
+
+
+[CSS]
+cmd=vscode-css-language-server --stdio
+extra_identifier_characters=-
+send_did_change_configuration=true
+autocomplete_use_snippets=true
+use_without_project=true
+use_outside_project_dir=true
+#rpc_log=stdout
+#rpc_log_full=true
+#show_server_stderr=true
+
+
+[Dart]
+cmd=dart language-server --protocol=lsp
+# everything except ( which conflicts with signature help
+autocomplete_trigger_sequences=.;=;$;";';{;/;:
+semantic_tokens_enable=true
+#rpc_log=stdout
+#rpc_log_full=true
+#show_server_stderr=true
+
+
+[Go]
+cmd=gopls
+autocomplete_apply_additional_edits=true
+lang_id_mappings=go.mod;go.mod;go.sum;go.sum;gotmpl;*tmpl
+semantic_tokens_enable=true
+semantic_tokens_type_style=17;#00007f;255;255;17
+format_on_save=true
+command_on_save_regex=Organize Imports
+progress_bar_enable=false
+#rpc_log=stdout
+#rpc_log_full=true
+#show_server_stderr=true
+
+
+[Haskell]
+cmd=haskell-language-server-wrapper --lsp
+# Full semantic tokens work but are kind of useless as Scintilla already
+# highlights types
+semantic_tokens_enable=false
+#semantic_tokens_force_full=true
+#initialization_options={"plugin": {"semanticTokens": {"config": { }, "globalOn": true}}}
+#semantic_tokens_type_style=17;#00007f;255;255;17
+#rpc_log=stdout
+#rpc_log_full=true
+#show_server_stderr=true
+
+
+[HTML]
+cmd=vscode-html-language-server --stdio
+extra_identifier_characters=&
+send_did_change_configuration=true
+autocomplete_use_snippets=true
+use_without_project=true
+use_outside_project_dir=true
+#rpc_log=stdout
+#rpc_log_full=true
+#show_server_stderr=true
+
+
+[Java]
+cmd=jdtls
+autocomplete_use_label=false
+#semantic_tokens_enable=true
+#rpc_log=stdout
+#rpc_log_full=true
+#show_server_stderr=true
+
+
+[JSON]
+cmd=vscode-json-languageserver --stdio
+#initialization_options={"provideFormatter": true, "json": { "schemas": [ { "fileMatch": [ "*.json"], "url": "file:///home/parallels/schema.json"}]}}
+send_did_change_configuration=true
+autocomplete_use_snippets=true
+use_without_project=true
+use_outside_project_dir=true
+#formatting_options={ "tabSize": 4, "insertSpaces": true }
+#rpc_log=stdout
+#rpc_log_full=true
+#show_server_stderr=true
+
+
+[LaTeX]
+cmd=texlab
+autocomplete_use_snippets=true
+extra_identifier_characters=:
+use_without_project=true
+use_outside_project_dir=true
+#rpc_log=stdout
+#rpc_log_full=true
+#show_server_stderr=true
+
+
+[Lua]
+cmd=lua-language-server
+autocomplete_use_label=false
+autocomplete_hide_after_words=do;then;true;false;end;else
+use_outside_project_dir=true
+use_without_project=true
+#rpc_log=stdout
+#rpc_log_full=true
+#show_server_stderr=true
+
+
+[Nix]
+cmd=nil
+use_without_project=true
+use_outside_project_dir=true
+extra_identifier_characters=-'
+#rpc_log=stdout
+#rpc_log_full=true
+#show_server_stderr=true
+
+
+[PHP]
+# Note: Server returns highlighting indices off by 1 and highlighting doesn't work
+cmd=phpactor.phar language-server
+autocomplete_trigger_sequences=:;>;$;[;@;';\;\\
+extra_identifier_characters=$
+#rpc_log=stdout
+#rpc_log_full=true
+#show_server_stderr=true
+
+
+[Python]
+# pip install pyright (or: pipx install pyright)
+cmd=pyright-langserver --stdio
+cmd=pyright-langserver --stdio
+# alternatively pylsp, jedi, ruff
+#cmd=pylsp
+#cmd=jedi-language-server
+#cmd=ruff server
+use_outside_project_dir=true
+use_without_project=true
+#rpc_log=stdout
+#rpc_log_full=true
+#show_server_stderr=true
+
+
+[Ruby]
+cmd=solargraph stdio
+#rpc_log=stdout
+#rpc_log_full=true
+#show_server_stderr=true
+
+
+[Rust]
+cmd=rust-analyzer
+semantic_tokens_enable=true
+autocomplete_trigger_sequences=:;.;'
+#rpc_log=stdout
+#rpc_log_full=true
+#show_server_stderr=true
+
+
+[Sh]
+cmd=bash-language-server start
+autocomplete_use_snippets=true
+use_outside_project_dir=true
+use_without_project=true
+#rpc_log=stdout
+#rpc_log_full=true
+#show_server_stderr=true
+
+
+[TypeScript]
+cmd=typescript-language-server --stdio
+semantic_tokens_enable=true
+use_outside_project_dir=true
+use_without_project=true
+#rpc_log=stdout
+#rpc_log_full=true
+#show_server_stderr=true
+
+
+[Javascript]
+use=TypeScript
+
+
+[XML]
+cmd=lemminx
+autocomplete_use_snippets=true
+diagnostics_statusbar_severity=4
+use_without_project=true
+use_outside_project_dir=true
+autocomplete_in_strings=true
+# see https://github.com/eclipse/lemminx/blob/main/docs/Configuration.md
+#initialization_options_file=/home/some_user/init_options.json
+#formatting_options={ "tabSize": 4, "insertSpaces": true }
+#rpc_log=stdout
+#rpc_log_full=true
+#show_server_stderr=true
+
+
+[YAML]
+cmd=yaml-language-server --stdio
+#initialization_options={"yaml": {"schemas": { "/home/parallels/schema.json": "*"}}}
+use_without_project=true
+use_outside_project_dir=true
+#formatting_options={ "tabSize": 4, "insertSpaces": true }
+#rpc_log=stdout
+#rpc_log_full=true
+#show_server_stderr=true
+
+
+[Zig]
+cmd=zls
+semantic_tokens_enable=true
+#autocomplete_use_snippets=true
+#rpc_log=stdout
+#rpc_log_full=true
+#show_server_stderr=true
+
+
+# TODO: help needed! Only the above defined language servers have been tested
+# (lightly). If you know some other working language server or find a problem
+# with the settings above, please open an issue report or a pull request
+# on Github.
Modified: lsp/deps/Makefile.am
78 lines changed, 78 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,78 @@
+include $(top_srcdir)/build/vars.build.mk
+
+noinst_LTLIBRARIES = libjsonrpc.la
+
+json_glib_srcs = \
+ json-glib/json-array.c \
+ json-glib/json-builder.c \
+ json-glib/json-builder.h \
+ json-glib/json-debug.c \
+ json-glib/json-debug.h \
+ json-glib/json-enum-types.c \
+ json-glib/json-enum-types.h \
+ json-glib/json-gboxed.c \
+ json-glib/json-generator.c \
+ json-glib/json-generator.h \
+ json-glib/json-glib.h \
+ json-glib/json-gobject.c \
+ json-glib/json-gobject.h \
+ json-glib/json-gobject-private.h \
+ json-glib/json-gvariant.c \
+ json-glib/json-gvariant.h \
+ json-glib/json-node.c \
+ json-glib/json-object.c \
+ json-glib/json-parser.c \
+ json-glib/json-parser.h \
+ json-glib/json-path.c \
+ json-glib/json-path.h \
+ json-glib/json-reader.c \
+ json-glib/json-reader.h \
+ json-glib/json-scanner.c \
+ json-glib/json-scanner.h \
+ json-glib/json-serializable.c \
+ json-glib/json-types.h \
+ json-glib/json-types-private.h \
+ json-glib/json-utils.c \
+ json-glib/json-utils.h \
+ json-glib/json-value.c \
+ json-glib/json-version.h \
+ json-glib/json-version-macros.h
+
+jsonrpc_glib_srcs = \
+ jsonrpc-glib/jsonrpc-client.c \
+ jsonrpc-glib/jsonrpc-client.h \
+ jsonrpc-glib/jsonrpc-glib.h \
+ jsonrpc-glib/jsonrpc-input-stream.c \
+ jsonrpc-glib/jsonrpc-input-stream.h \
+ jsonrpc-glib/jsonrpc-input-stream-private.h \
+ jsonrpc-glib/jsonrpc-marshalers.c \
+ jsonrpc-glib/jsonrpc-marshalers.h \
+ jsonrpc-glib/jsonrpc-message.c \
+ jsonrpc-glib/jsonrpc-message.h \
+ jsonrpc-glib/jsonrpc-output-stream.c \
+ jsonrpc-glib/jsonrpc-output-stream.h \
+ jsonrpc-glib/jsonrpc-server.c \
+ jsonrpc-glib/jsonrpc-server.h \
+ jsonrpc-glib/jsonrpc-version.h \
+ jsonrpc-glib/jsonrpc-version-macros.h
+
+if ENABLE_BUILTIN_JSONRPC
+
+libjsonrpc_la_SOURCES = \
+ $(json_glib_srcs) \
+ $(jsonrpc_glib_srcs)
+
+libjsonrpc_la_CPPFLAGS = $(AM_CPPFLAGS) \
+ -DG_LOG_DOMAIN=\"LSP\" \
+ -DJSON_COMPILATION \
+ -DJSONRPC_GLIB_COMPILATION \
+ -I$(top_srcdir)/lsp/deps/json-glib \
+ -I$(top_srcdir)/lsp/deps/jsonrpc-glib
+libjsonrpc_la_CFLAGS = $(AM_CFLAGS)
+
+# do not enable cppcheck for json-glib or jsonrpc-glib as it generates lots of
+# false positives and it's not "our" code anyway
+#
+# include $(top_srcdir)/build/cppcheck.mk
+
+endif
Modified: lsp/deps/json-glib/json-array.c
838 lines changed, 838 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,838 @@
+/* json-array.c - JSON array implementation
+ *
+ * This file is part of JSON-GLib
+ * Copyright (C) 2007 OpenedHand Ltd.
+ * Copyright (C) 2009 Intel Corp.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ * Emmanuele Bassi <ebassi(a)linux.intel.com>
+ */
+
+#include "config.h"
+
+#include "json-types-private.h"
+
+/**
+ * JsonArray:
+ *
+ * `JsonArray` is the representation of the array type inside JSON.
+ *
+ * A `JsonArray` contains [struct(a)Json.Node] elements, which may contain
+ * fundamental types, other arrays or objects.
+ *
+ * Since arrays can be arbitrarily big, copying them can be expensive; for
+ * this reason, they are reference counted. You can control the lifetime of
+ * a `JsonArray` using [method(a)Json.Array.ref] and [method(a)Json.Array.unref].
+ *
+ * To append an element, use [method(a)Json.Array.add_element].
+ *
+ * To extract an element at a given index, use [method(a)Json.Array.get_element].
+ *
+ * To retrieve the entire array in list form, use [method(a)Json.Array.get_elements].
+ *
+ * To retrieve the length of the array, use [method(a)Json.Array.get_length].
+ */
+
+G_DEFINE_BOXED_TYPE (JsonArray, json_array, json_array_ref, json_array_unref);
+
+/**
+ * json_array_new: (constructor)
+ *
+ * Creates a new array.
+ *
+ * Return value: (transfer full): the newly created array
+ */
+JsonArray *
+json_array_new (void)
+{
+ JsonArray *array;
+
+ array = g_slice_new0 (JsonArray);
+
+ array->ref_count = 1;
+ array->elements = g_ptr_array_new ();
+
+ return array;
+}
+
+/**
+ * json_array_sized_new: (constructor)
+ * @n_elements: number of slots to pre-allocate
+ *
+ * Creates a new array with `n_elements` slots already allocated.
+ *
+ * Return value: (transfer full): the newly created array
+ */
+JsonArray *
+json_array_sized_new (guint n_elements)
+{
+ JsonArray *array;
+
+ array = g_slice_new0 (JsonArray);
+
+ array->ref_count = 1;
+ array->elements = g_ptr_array_sized_new (n_elements);
+
+ return array;
+}
+
+/**
+ * json_array_ref:
+ * @array: the array to reference
+ *
+ * Acquires a reference on the given array.
+ *
+ * Return value: (transfer none): the passed array, with the reference count
+ * increased by one
+ */
+JsonArray *
+json_array_ref (JsonArray *array)
+{
+ g_return_val_if_fail (array != NULL, NULL);
+ g_return_val_if_fail (array->ref_count > 0, NULL);
+
+ array->ref_count++;
+
+ return array;
+}
+
+/**
+ * json_array_unref:
+ * @array: the array to unreference
+ *
+ * Releases a reference on the given array.
+ *
+ * If the reference count reaches zero, the array is destroyed and all
+ * its allocated resources are freed.
+ */
+void
+json_array_unref (JsonArray *array)
+{
+ g_return_if_fail (array != NULL);
+ g_return_if_fail (array->ref_count > 0);
+
+ if (--array->ref_count == 0)
+ {
+ guint i;
+
+ for (i = 0; i < array->elements->len; i++)
+ json_node_unref (g_ptr_array_index (array->elements, i));
+
+ g_ptr_array_free (array->elements, TRUE);
+ array->elements = NULL;
+
+ g_slice_free (JsonArray, array);
+ }
+}
+
+/**
+ * json_array_seal:
+ * @array: the array to seal
+ *
+ * Seals the given array, making it immutable to further changes.
+ *
+ * This function will recursively seal all elements in the array too.
+ *
+ * If the `array` is already immutable, this is a no-op.
+ *
+ * Since: 1.2
+ */
+void
+json_array_seal (JsonArray *array)
+{
+ guint i;
+
+ g_return_if_fail (array != NULL);
+ g_return_if_fail (array->ref_count > 0);
+
+ if (array->immutable)
+ return;
+
+ /* Propagate to all members. */
+ for (i = 0; i < array->elements->len; i++)
+ json_node_seal (g_ptr_array_index (array->elements, i));
+
+ array->immutable_hash = json_array_hash (array);
+ array->immutable = TRUE;
+}
+
+/**
+ * json_array_is_immutable:
+ * @array: a JSON array
+ *
+ * Check whether the given `array` has been marked as immutable by calling
+ * [method(a)Json.Array.seal] on it.
+ *
+ * Since: 1.2
+ * Returns: %TRUE if the array is immutable
+ */
+gboolean
+json_array_is_immutable (JsonArray *array)
+{
+ g_return_val_if_fail (array != NULL, FALSE);
+ g_return_val_if_fail (array->ref_count > 0, FALSE);
+
+ return array->immutable;
+}
+
+/**
+ * json_array_get_elements:
+ * @array: a JSON array
+ *
+ * Retrieves all the elements of an array as a list of nodes.
+ *
+ * Return value: (element-type JsonNode) (transfer container) (nullable): the elements
+ * of the array
+ */
+GList *
+json_array_get_elements (JsonArray *array)
+{
+ GList *retval;
+ guint i;
+
+ g_return_val_if_fail (array != NULL, NULL);
+
+ retval = NULL;
+ for (i = 0; i < array->elements->len; i++)
+ retval = g_list_prepend (retval,
+ g_ptr_array_index (array->elements, i));
+
+ return g_list_reverse (retval);
+}
+
+/**
+ * json_array_dup_element:
+ * @array: a JSON array
+ * @index_: the index of the element to retrieve
+ *
+ * Retrieves a copy of the element at the given position in the array.
+ *
+ * Return value: (transfer full): a copy of the element at the given position
+ *
+ * Since: 0.6
+ */
+JsonNode *
+json_array_dup_element (JsonArray *array,
+ guint index_)
+{
+ JsonNode *retval;
+
+ g_return_val_if_fail (array != NULL, NULL);
+ g_return_val_if_fail (index_ < array->elements->len, NULL);
+
+ retval = json_array_get_element (array, index_);
+ if (!retval)
+ return NULL;
+
+ return json_node_copy (retval);
+}
+
+/**
+ * json_array_get_element:
+ * @array: a JSON array
+ * @index_: the index of the element to retrieve
+ *
+ * Retrieves the element at the given position in the array.
+ *
+ * Return value: (transfer none): the element at the given position
+ */
+JsonNode *
+json_array_get_element (JsonArray *array,
+ guint index_)
+{
+ g_return_val_if_fail (array != NULL, NULL);
+ g_return_val_if_fail (index_ < array->elements->len, NULL);
+
+ return g_ptr_array_index (array->elements, index_);
+}
+
+/**
+ * json_array_get_int_element:
+ * @array: a JSON array
+ * @index_: the index of the element to retrieve
+ *
+ * Conveniently retrieves the integer value of the element at the given
+ * position inside an array.
+ *
+ * See also: [method(a)Json.Array.get_element], [method(a)Json.Node.get_int]
+ *
+ * Return value: the integer value
+ *
+ * Since: 0.8
+ */
+gint64
+json_array_get_int_element (JsonArray *array,
+ guint index_)
+{
+ JsonNode *node;
+
+ g_return_val_if_fail (array != NULL, 0);
+ g_return_val_if_fail (index_ < array->elements->len, 0);
+
+ node = g_ptr_array_index (array->elements, index_);
+ g_return_val_if_fail (node != NULL, 0);
+ g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE, 0);
+
+ return json_node_get_int (node);
+}
+
+/**
+ * json_array_get_double_element:
+ * @array: a JSON array
+ * @index_: the index of the element to retrieve
+ *
+ * Conveniently retrieves the floating point value of the element at
+ * the given position inside an array.
+ *
+ * See also: [method(a)Json.Array.get_element], [method(a)Json.Node.get_double]
+ *
+ * Return value: the floating point value
+ *
+ * Since: 0.8
+ */
+gdouble
+json_array_get_double_element (JsonArray *array,
+ guint index_)
+{
+ JsonNode *node;
+
+ g_return_val_if_fail (array != NULL, 0.0);
+ g_return_val_if_fail (index_ < array->elements->len, 0.0);
+
+ node = g_ptr_array_index (array->elements, index_);
+ g_return_val_if_fail (node != NULL, 0.0);
+ g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE, 0.0);
+
+ return json_node_get_double (node);
+}
+
+/**
+ * json_array_get_boolean_element:
+ * @array: a JSON array
+ * @index_: the index of the element to retrieve
+ *
+ * Conveniently retrieves the boolean value of the element at the given
+ * position inside an array.
+ *
+ * See also: [method(a)Json.Array.get_element], [method(a)Json.Node.get_boolean]
+ *
+ * Return value: the boolean value
+ *
+ * Since: 0.8
+ */
+gboolean
+json_array_get_boolean_element (JsonArray *array,
+ guint index_)
+{
+ JsonNode *node;
+
+ g_return_val_if_fail (array != NULL, FALSE);
+ g_return_val_if_fail (index_ < array->elements->len, FALSE);
+
+ node = g_ptr_array_index (array->elements, index_);
+ g_return_val_if_fail (node != NULL, FALSE);
+ g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE, FALSE);
+
+ return json_node_get_boolean (node);
+}
+
+/**
+ * json_array_get_string_element:
+ * @array: a JSON array
+ * @index_: the index of the element to retrieve
+ *
+ * Conveniently retrieves the string value of the element at the given
+ * position inside an array.
+ *
+ * See also: [method(a)Json.Array.get_element], [method(a)Json.Node.get_string]
+ *
+ * Return value: (transfer none): the string value
+ *
+ * Since: 0.8
+ */
+const gchar *
+json_array_get_string_element (JsonArray *array,
+ guint index_)
+{
+ JsonNode *node;
+
+ g_return_val_if_fail (array != NULL, NULL);
+ g_return_val_if_fail (index_ < array->elements->len, NULL);
+
+ node = g_ptr_array_index (array->elements, index_);
+ g_return_val_if_fail (node != NULL, NULL);
+ g_return_val_if_fail (JSON_NODE_HOLDS_VALUE (node) || JSON_NODE_HOLDS_NULL (node), NULL);
+
+ if (JSON_NODE_HOLDS_NULL (node))
+ return NULL;
+
+ return json_node_get_string (node);
+}
+
+/**
+ * json_array_get_null_element:
+ * @array: a JSON array
+ * @index_: the index of the element to retrieve
+ *
+ * Conveniently checks whether the element at the given position inside the
+ * array contains a `null` value.
+ *
+ * See also: [method(a)Json.Array.get_element], [method(a)Json.Node.is_null]
+ *
+ * Return value: `TRUE` if the element is `null`
+ *
+ * Since: 0.8
+ */
+gboolean
+json_array_get_null_element (JsonArray *array,
+ guint index_)
+{
+ JsonNode *node;
+
+ g_return_val_if_fail (array != NULL, FALSE);
+ g_return_val_if_fail (index_ < array->elements->len, FALSE);
+
+ node = g_ptr_array_index (array->elements, index_);
+ g_return_val_if_fail (node != NULL, FALSE);
+
+ if (JSON_NODE_HOLDS_NULL (node))
+ return TRUE;
+
+ if (JSON_NODE_HOLDS_ARRAY (node))
+ return json_node_get_array (node) == NULL;
+
+ if (JSON_NODE_HOLDS_OBJECT (node))
+ return json_node_get_object (node) == NULL;
+
+ return FALSE;
+}
+
+/**
+ * json_array_get_array_element:
+ * @array: a JSON array
+ * @index_: the index of the element to retrieve
+ *
+ * Conveniently retrieves the array at the given position inside an array.
+ *
+ * See also: [method(a)Json.Array.get_element], [method(a)Json.Node.get_array]
+ *
+ * Return value: (transfer none): the array
+ *
+ * Since: 0.8
+ */
+JsonArray *
+json_array_get_array_element (JsonArray *array,
+ guint index_)
+{
+ JsonNode *node;
+
+ g_return_val_if_fail (array != NULL, NULL);
+ g_return_val_if_fail (index_ < array->elements->len, NULL);
+
+ node = g_ptr_array_index (array->elements, index_);
+ g_return_val_if_fail (node != NULL, NULL);
+ g_return_val_if_fail (JSON_NODE_HOLDS_ARRAY (node) || JSON_NODE_HOLDS_NULL (node), NULL);
+
+ if (JSON_NODE_HOLDS_NULL (node))
+ return NULL;
+
+ return json_node_get_array (node);
+}
+
+/**
+ * json_array_get_object_element:
+ * @array: a JSON array
+ * @index_: the index of the element to retrieve
+ *
+ * Conveniently retrieves the object at the given position inside an array.
+ *
+ * See also: [method(a)Json.Array.get_element], [method(a)Json.Node.get_object]
+ *
+ * Return value: (transfer none): the object
+ *
+ * Since: 0.8
+ */
+JsonObject *
+json_array_get_object_element (JsonArray *array,
+ guint index_)
+{
+ JsonNode *node;
+
+ g_return_val_if_fail (array != NULL, NULL);
+ g_return_val_if_fail (index_ < array->elements->len, NULL);
+
+ node = g_ptr_array_index (array->elements, index_);
+ g_return_val_if_fail (node != NULL, NULL);
+ g_return_val_if_fail (JSON_NODE_HOLDS_OBJECT (node) || JSON_NODE_HOLDS_NULL (node), NULL);
+
+ if (JSON_NODE_HOLDS_NULL (node))
+ return NULL;
+
+ return json_node_get_object (node);
+}
+
+/**
+ * json_array_get_length:
+ * @array: a JSON array
+ *
+ * Retrieves the length of the given array
+ *
+ * Return value: the length of the array
+ */
+guint
+json_array_get_length (JsonArray *array)
+{
+ g_return_val_if_fail (array != NULL, 0);
+
+ return array->elements->len;
+}
+
+/**
+ * json_array_add_element:
+ * @array: a JSON array
+ * @node: (transfer full): the element to add
+ *
+ * Appends the given `node` inside an array.
+ */
+void
+json_array_add_element (JsonArray *array,
+ JsonNode *node)
+{
+ g_return_if_fail (array != NULL);
+ g_return_if_fail (node != NULL);
+
+ g_ptr_array_add (array->elements, node);
+}
+
+/**
+ * json_array_add_int_element:
+ * @array: a JSON array
+ * @value: the integer value to add
+ *
+ * Conveniently adds the given integer value into an array.
+ *
+ * See also: [method(a)Json.Array.add_element], [method(a)Json.Node.set_int]
+ *
+ * Since: 0.8
+ */
+void
+json_array_add_int_element (JsonArray *array,
+ gint64 value)
+{
+ g_return_if_fail (array != NULL);
+
+ json_array_add_element (array, json_node_init_int (json_node_alloc (), value));
+}
+
+/**
+ * json_array_add_double_element:
+ * @array: a JSON array
+ * @value: the floating point value to add
+ *
+ * Conveniently adds the given floating point value into an array.
+ *
+ * See also: [method(a)Json.Array.add_element], [method(a)Json.Node.set_double]
+ *
+ * Since: 0.8
+ */
+void
+json_array_add_double_element (JsonArray *array,
+ gdouble value)
+{
+ g_return_if_fail (array != NULL);
+
+ json_array_add_element (array, json_node_init_double (json_node_alloc (), value));
+}
+
+/**
+ * json_array_add_boolean_element:
+ * @array: a JSON array
+ * @value: the boolean value to add
+ *
+ * Conveniently adds the given boolean value into an array.
+ *
+ * See also: [method(a)Json.Array.add_element], [method(a)Json.Node.set_boolean]
+ *
+ * Since: 0.8
+ */
+void
+json_array_add_boolean_element (JsonArray *array,
+ gboolean value)
+{
+ g_return_if_fail (array != NULL);
+
+ json_array_add_element (array, json_node_init_boolean (json_node_alloc (), value));
+}
+
+/**
+ * json_array_add_string_element:
+ * @array: a JSON array
+ * @value: the string value to add
+ *
+ * Conveniently adds the given string value into an array.
+ *
+ * See also: [method(a)Json.Array.add_element], [method(a)Json.Node.set_string]
+ *
+ * Since: 0.8
+ */
+void
+json_array_add_string_element (JsonArray *array,
+ const gchar *value)
+{
+ JsonNode *node;
+
+ g_return_if_fail (array != NULL);
+
+ node = json_node_alloc ();
+
+ if (value != NULL)
+ json_node_init_string (node, value);
+ else
+ json_node_init_null (node);
+
+ json_array_add_element (array, node);
+}
+
+/**
+ * json_array_add_null_element:
+ * @array: a JSON array
+ *
+ * Conveniently adds a `null` element into an array
+ *
+ * See also: [method(a)Json.Array.add_element], `JSON_NODE_NULL`
+ *
+ * Since: 0.8
+ */
+void
+json_array_add_null_element (JsonArray *array)
+{
+ g_return_if_fail (array != NULL);
+
+ json_array_add_element (array, json_node_init_null (json_node_alloc ()));
+}
+
+/**
+ * json_array_add_array_element:
+ * @array: a JSON array
+ * @value: (nullable) (transfer full): the array to add
+ *
+ * Conveniently adds an array element into an array.
+ *
+ * If `value` is `NULL`, a `null` element will be added instead.
+ *
+ * See also: [method(a)Json.Array.add_element], [method(a)Json.Node.take_array]
+ *
+ * Since: 0.8
+ */
+void
+json_array_add_array_element (JsonArray *array,
+ JsonArray *value)
+{
+ JsonNode *node;
+
+ g_return_if_fail (array != NULL);
+
+ node = json_node_alloc ();
+
+ if (value != NULL)
+ {
+ json_node_init_array (node, value);
+ json_array_unref (value);
+ }
+ else
+ json_node_init_null (node);
+
+ json_array_add_element (array, node);
+}
+
+/**
+ * json_array_add_object_element:
+ * @array: a JSON array
+ * @value: (transfer full) (nullable): the object to add
+ *
+ * Conveniently adds an object into an array.
+ *
+ * If `value` is `NULL`, a `null` element will be added instead.
+ *
+ * See also: [method(a)Json.Array.add_element], [method(a)Json.Node.take_object]
+ *
+ * Since: 0.8
+ */
+void
+json_array_add_object_element (JsonArray *array,
+ JsonObject *value)
+{
+ JsonNode *node;
+
+ g_return_if_fail (array != NULL);
+
+ node = json_node_alloc ();
+
+ if (value != NULL)
+ {
+ json_node_init_object (node, value);
+ json_object_unref (value);
+ }
+ else
+ json_node_init_null (node);
+
+ json_array_add_element (array, node);
+}
+
+/**
+ * json_array_remove_element:
+ * @array: a JSON array
+ * @index_: the position of the element to be removed
+ *
+ * Removes the element at the given position inside an array.
+ *
+ * This function will release the reference held on the element.
+ */
+void
+json_array_remove_element (JsonArray *array,
+ guint index_)
+{
+ g_return_if_fail (array != NULL);
+ g_return_if_fail (index_ < array->elements->len);
+
+ json_node_unref (g_ptr_array_remove_index (array->elements, index_));
+}
+
+/**
+ * json_array_foreach_element:
+ * @array: a JSON array
+ * @func: (scope call): the function to be called on each element
+ * @data: (closure): data to be passed to the function
+ *
+ * Iterates over all elements of an array, and calls a function on
+ * each one of them.
+ *
+ * It is safe to change the value of an element of the array while
+ * iterating over it, but it is not safe to add or remove elements
+ * from the array.
+ *
+ * Since: 0.8
+ */
+void
+json_array_foreach_element (JsonArray *array,
+ JsonArrayForeach func,
+ gpointer data)
+{
+ g_return_if_fail (array != NULL);
+ g_return_if_fail (func != NULL);
+
+ for (guint i = 0; i < array->elements->len; i++)
+ {
+ JsonNode *element_node;
+
+ element_node = g_ptr_array_index (array->elements, i);
+
+ (* func) (array, i, element_node, data);
+ }
+}
+
+/**
+ * json_array_hash:
+ * @key: (type JsonArray) (not nullable): a JSON array to hash
+ *
+ * Calculates a hash value for the given `key`.
+ *
+ * The hash is calculated over the array and all its elements, recursively.
+ *
+ * If the array is immutable, this is a fast operation; otherwise, it scales
+ * proportionally with the length of the array.
+ *
+ * Returns: hash value for the key
+ * Since: 1.2
+ */
+guint
+json_array_hash (gconstpointer key)
+{
+ JsonArray *array; /* unowned */
+ guint hash = 0;
+ guint i;
+
+ g_return_val_if_fail (key != NULL, 0);
+
+ array = (JsonArray *) key;
+
+ /* If the array is immutable, we can use the calculated hash. */
+ if (array->immutable)
+ return array->immutable_hash;
+
+ /* Otherwise, calculate the hash. */
+ for (i = 0; i < array->elements->len; i++)
+ {
+ JsonNode *node = g_ptr_array_index (array->elements, i);
+ hash ^= (i ^ json_node_hash (node));
+ }
+
+ return hash;
+}
+
+/**
+ * json_array_equal:
+ * @a: (type JsonArray) (not nullable): a JSON array
+ * @b: (type JsonArray) (not nullable): another JSON array
+ *
+ * Check whether two arrays are equal.
+ *
+ * Equality is defined as:
+ *
+ * - the array have the same number of elements
+ * - the values of elements in corresponding positions are equal
+ *
+ * Returns: `TRUE` if the arrays are equal, and `FALSE` otherwise
+ * Since: 1.2
+ */
+gboolean
+json_array_equal (gconstpointer a,
+ gconstpointer b)
+{
+ JsonArray *array_a, *array_b; /* unowned */
+ guint length_a, length_b, i;
+
+ g_return_val_if_fail (a != NULL, FALSE);
+ g_return_val_if_fail (b != NULL, FALSE);
+
+ array_a = (JsonArray *) a;
+ array_b = (JsonArray *) b;
+
+ /* Identity comparison. */
+ if (array_a == array_b)
+ return TRUE;
+
+ /* Check lengths. */
+ length_a = json_array_get_length (array_a);
+ length_b = json_array_get_length (array_b);
+
+ if (length_a != length_b)
+ return FALSE;
+
+ /* Check elements. */
+ for (i = 0; i < length_a; i++)
+ {
+ JsonNode *child_a, *child_b; /* unowned */
+
+ child_a = json_array_get_element (array_a, i);
+ child_b = json_array_get_element (array_b, i);
+
+ if (!json_node_equal (child_a, child_b))
+ return FALSE;
+ }
+
+ return TRUE;
+}
Modified: lsp/deps/json-glib/json-builder.c
845 lines changed, 845 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,845 @@
+/* json-generator.c - JSON tree builder
+ *
+ * This file is part of JSON-GLib
+ * Copyright (C) 2010 Luca Bruno <lethalman88(a)gmail.com>
+ * Copyright (C) 2015 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ * Luca Bruno <lethalman88(a)gmail.com>
+ * Philip Withnall <philip.withnall(a)collabora.co.uk>
+ */
+
+/**
+ * JsonBuilder:
+ *
+ * `JsonBuilder` provides an object for generating a JSON tree.
+ *
+ * The root of the JSON tree can be either a [struct(a)Json.Object] or a [struct(a)Json.Array].
+ * Thus the first call must necessarily be either
+ * [method(a)Json.Builder.begin_object] or [method(a)Json.Builder.begin_array].
+ *
+ * For convenience to language bindings, most `JsonBuilder` method return the
+ * instance, making it easy to chain function calls.
+ *
+ * ## Using `JsonBuilder`
+ *
+ * ```c
+ * g_autoptr(JsonBuilder) builder = json_builder_new ();
+ *
+ * json_builder_begin_object (builder);
+ *
+ * json_builder_set_member_name (builder, "url");
+ * json_builder_add_string_value (builder, "http://www.gnome.org/img/flash/two-thirty.png");
+ *
+ * json_builder_set_member_name (builder, "size");
+ * json_builder_begin_array (builder);
+ * json_builder_add_int_value (builder, 652);
+ * json_builder_add_int_value (builder, 242);
+ * json_builder_end_array (builder);
+ *
+ * json_builder_end_object (builder);
+ *
+ * g_autoptr(JsonNode) root = json_builder_get_root (builder);
+ *
+ * g_autoptr(JsonGenerator) gen = json_generator_new ();
+ * json_generator_set_root (gen, root);
+ * g_autofree char *str = json_generator_to_data (gen, NULL);
+ *
+ * // str now contains the following JSON data
+ * // { "url" : "http://www.gnome.org/img/flash/two-thirty.png", "size" : [ 652, 242 ] }
+ * ```
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "json-types-private.h"
+
+#include "json-builder.h"
+
+struct _JsonBuilderPrivate
+{
+ GQueue *stack;
+ JsonNode *root;
+ gboolean immutable;
+};
+
+enum
+{
+ PROP_IMMUTABLE = 1,
+ PROP_LAST
+};
+
+static GParamSpec *builder_props[PROP_LAST] = { NULL, };
+
+typedef enum
+{
+ JSON_BUILDER_MODE_OBJECT,
+ JSON_BUILDER_MODE_ARRAY,
+ JSON_BUILDER_MODE_MEMBER
+} JsonBuilderMode;
+
+typedef struct
+{
+ JsonBuilderMode mode;
+
+ union
+ {
+ JsonObject *object;
+ JsonArray *array;
+ } data;
+ gchar *member_name;
+} JsonBuilderState;
+
+static void
+json_builder_state_free (JsonBuilderState *state)
+{
+ if (G_LIKELY (state))
+ {
+ switch (state->mode)
+ {
+ case JSON_BUILDER_MODE_OBJECT:
+ case JSON_BUILDER_MODE_MEMBER:
+ json_object_unref (state->data.object);
+ g_free (state->member_name);
+ state->data.object = NULL;
+ state->member_name = NULL;
+ break;
+
+ case JSON_BUILDER_MODE_ARRAY:
+ json_array_unref (state->data.array);
+ state->data.array = NULL;
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+
+ g_slice_free (JsonBuilderState, state);
+ }
+}
+
+G_DEFINE_TYPE_WITH_PRIVATE (JsonBuilder, json_builder, G_TYPE_OBJECT)
+
+static void
+json_builder_free_all_state (JsonBuilder *builder)
+{
+ JsonBuilderState *state;
+
+ while (!g_queue_is_empty (builder->priv->stack))
+ {
+ state = g_queue_pop_head (builder->priv->stack);
+ json_builder_state_free (state);
+ }
+
+ if (builder->priv->root)
+ {
+ json_node_unref (builder->priv->root);
+ builder->priv->root = NULL;
+ }
+}
+
+static void
+json_builder_finalize (GObject *gobject)
+{
+ JsonBuilderPrivate *priv = json_builder_get_instance_private ((JsonBuilder *) gobject);
+
+ json_builder_free_all_state (JSON_BUILDER (gobject));
+
+ g_queue_free (priv->stack);
+ priv->stack = NULL;
+
+ G_OBJECT_CLASS (json_builder_parent_class)->finalize (gobject);
+}
+
+static void
+json_builder_set_property (GObject *gobject,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ JsonBuilderPrivate *priv = JSON_BUILDER (gobject)->priv;
+
+ switch (prop_id)
+ {
+ case PROP_IMMUTABLE:
+ /* Construct-only. */
+ priv->immutable = g_value_get_boolean (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+json_builder_get_property (GObject *gobject,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ JsonBuilderPrivate *priv = JSON_BUILDER (gobject)->priv;
+
+ switch (prop_id)
+ {
+ case PROP_IMMUTABLE:
+ g_value_set_boolean (value, priv->immutable);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+json_builder_class_init (JsonBuilderClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ /**
+ * JsonBuilder:immutable:
+ *
+ * Whether the tree should be immutable when created.
+ *
+ * Making the output immutable on creation avoids the expense
+ * of traversing it to make it immutable later.
+ *
+ * Since: 1.2
+ */
+ builder_props[PROP_IMMUTABLE] =
+ g_param_spec_boolean ("immutable",
+ "Immutable Output",
+ "Whether the builder output is immutable.",
+ FALSE,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
+
+ gobject_class->set_property = json_builder_set_property;
+ gobject_class->get_property = json_builder_get_property;
+ gobject_class->finalize = json_builder_finalize;
+
+ g_object_class_install_properties (gobject_class, PROP_LAST, builder_props);
+}
+
+static void
+json_builder_init (JsonBuilder *builder)
+{
+ JsonBuilderPrivate *priv = json_builder_get_instance_private (builder);
+
+ builder->priv = priv;
+
+ priv->stack = g_queue_new ();
+ priv->root = NULL;
+}
+
+static inline JsonBuilderMode
+json_builder_current_mode (JsonBuilder *builder)
+{
+ JsonBuilderState *state = g_queue_peek_head (builder->priv->stack);
+ return state->mode;
+}
+
+static inline gboolean
+json_builder_is_valid_add_mode (JsonBuilder *builder)
+{
+ JsonBuilderMode mode = json_builder_current_mode (builder);
+ return mode == JSON_BUILDER_MODE_MEMBER || mode == JSON_BUILDER_MODE_ARRAY;
+}
+
+/**
+ * json_builder_new:
+ *
+ * Creates a new `JsonBuilder`.
+ *
+ * You can use this object to generate a JSON tree and obtain the root node.
+ *
+ * Return value: the newly created builder instance
+ */
+JsonBuilder *
+json_builder_new (void)
+{
+ return g_object_new (JSON_TYPE_BUILDER, NULL);
+}
+
+/**
+ * json_builder_new_immutable: (constructor)
+ *
+ * Creates a new, immutable `JsonBuilder` instance.
+ *
+ * It is equivalent to setting the [property@Json.Builder:immutable] property
+ * set to `TRUE` at construction time.
+ *
+ * Since: 1.2
+ * Returns: (transfer full): the newly create builder instance
+ */
+JsonBuilder *
+json_builder_new_immutable (void)
+{
+ return g_object_new (JSON_TYPE_BUILDER, "immutable", TRUE, NULL);
+}
+
+/**
+ * json_builder_get_root:
+ * @builder: a builder
+ *
+ * Returns the root of the currently constructed tree.
+ *
+ * if the build is incomplete (ie: if there are any opened objects, or any
+ * open object members and array elements) then this function will return
+ * `NULL`.
+ *
+ * Return value: (nullable) (transfer full): the root node
+ */
+JsonNode *
+json_builder_get_root (JsonBuilder *builder)
+{
+ JsonNode *root = NULL;
+
+ g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
+
+ if (builder->priv->root)
+ root = json_node_copy (builder->priv->root);
+
+ /* Sanity check. */
+ g_assert (!builder->priv->immutable ||
+ root == NULL ||
+ json_node_is_immutable (root));
+
+ return root;
+}
+
+/**
+ * json_builder_reset:
+ * @builder: a builder
+ *
+ * Resets the state of the builder back to its initial state.
+ */
+void
+json_builder_reset (JsonBuilder *builder)
+{
+ g_return_if_fail (JSON_IS_BUILDER (builder));
+
+ json_builder_free_all_state (builder);
+}
+
+/**
+ * json_builder_begin_object:
+ * @builder: a builder
+ *
+ * Opens an object inside the given builder.
+ *
+ * You can add a new member to the object by using [method(a)Json.Builder.set_member_name],
+ * followed by [method(a)Json.Builder.add_value].
+ *
+ * Once you added all members to the object, you must call [method(a)Json.Builder.end_object]
+ * to close the object.
+ *
+ * If the builder is in an inconsistent state, this function will return `NULL`.
+ *
+ * Return value: (nullable) (transfer none): the builder instance
+ */
+JsonBuilder *
+json_builder_begin_object (JsonBuilder *builder)
+{
+ JsonObject *object;
+ JsonBuilderState *state;
+ JsonBuilderState *cur_state;
+
+ g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
+ g_return_val_if_fail (builder->priv->root == NULL, NULL);
+ g_return_val_if_fail (g_queue_is_empty (builder->priv->stack) || json_builder_is_valid_add_mode (builder), NULL);
+
+ object = json_object_new ();
+ cur_state = g_queue_peek_head (builder->priv->stack);
+ if (cur_state)
+ {
+ switch (cur_state->mode)
+ {
+ case JSON_BUILDER_MODE_ARRAY:
+ json_array_add_object_element (cur_state->data.array, json_object_ref (object));
+ break;
+
+ case JSON_BUILDER_MODE_MEMBER:
+ json_object_set_object_member (cur_state->data.object, cur_state->member_name, json_object_ref (object));
+ g_free (cur_state->member_name);
+ cur_state->member_name = NULL;
+ cur_state->mode = JSON_BUILDER_MODE_OBJECT;
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+ }
+
+ state = g_slice_new (JsonBuilderState);
+ state->data.object = object;
+ state->member_name = NULL;
+ state->mode = JSON_BUILDER_MODE_OBJECT;
+ g_queue_push_head (builder->priv->stack, state);
+
+ return builder;
+}
+
+/**
+ * json_builder_end_object:
+ * @builder: a builder
+ *
+ * Closes the object inside the given builder that was opened by the most
+ * recent call to [method(a)Json.Builder.begin_object].
+ *
+ * This function cannot be called after [method(a)Json.Builder.set_member_name].
+ *
+ * Return value: (nullable) (transfer none): the builder instance
+ */
+JsonBuilder *
+json_builder_end_object (JsonBuilder *builder)
+{
+ JsonBuilderState *state;
+
+ g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
+ g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL);
+ g_return_val_if_fail (json_builder_current_mode (builder) == JSON_BUILDER_MODE_OBJECT, NULL);
+
+ state = g_queue_pop_head (builder->priv->stack);
+
+ if (builder->priv->immutable)
+ json_object_seal (state->data.object);
+
+ if (g_queue_is_empty (builder->priv->stack))
+ {
+ builder->priv->root = json_node_new (JSON_NODE_OBJECT);
+ json_node_take_object (builder->priv->root, json_object_ref (state->data.object));
+
+ if (builder->priv->immutable)
+ json_node_seal (builder->priv->root);
+ }
+
+ json_builder_state_free (state);
+
+ return builder;
+}
+
+/**
+ * json_builder_begin_array:
+ * @builder: a builder
+ *
+ * Opens an array inside the given builder.
+ *
+ * You can add a new element to the array by using [method(a)Json.Builder.add_value].
+ *
+ * Once you added all elements to the array, you must call
+ * [method(a)Json.Builder.end_array] to close the array.
+ *
+ * Return value: (nullable) (transfer none): the builder instance
+ */
+JsonBuilder *
+json_builder_begin_array (JsonBuilder *builder)
+{
+ JsonArray *array;
+ JsonBuilderState *state;
+ JsonBuilderState *cur_state;
+
+ g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
+ g_return_val_if_fail (builder->priv->root == NULL, NULL);
+ g_return_val_if_fail (g_queue_is_empty (builder->priv->stack) || json_builder_is_valid_add_mode (builder), NULL);
+
+ array = json_array_new ();
+ cur_state = g_queue_peek_head (builder->priv->stack);
+ if (cur_state)
+ {
+ switch (cur_state->mode)
+ {
+ case JSON_BUILDER_MODE_ARRAY:
+ json_array_add_array_element (cur_state->data.array, json_array_ref (array));
+ break;
+
+ case JSON_BUILDER_MODE_MEMBER:
+ json_object_set_array_member (cur_state->data.object, cur_state->member_name, json_array_ref (array));
+ g_free (cur_state->member_name);
+ cur_state->member_name = NULL;
+ cur_state->mode = JSON_BUILDER_MODE_OBJECT;
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+ }
+
+ state = g_slice_new (JsonBuilderState);
+ state->data.array = array;
+ state->mode = JSON_BUILDER_MODE_ARRAY;
+ g_queue_push_head (builder->priv->stack, state);
+
+ return builder;
+}
+
+/**
+ * json_builder_end_array:
+ * @builder: a builder
+ *
+ * Closes the array inside the given builder that was opened by the most
+ * recent call to [method(a)Json.Builder.begin_array].
+ *
+ * This function cannot be called after [method(a)Json.Builder.set_member_name].
+ *
+ * Return value: (nullable) (transfer none): the builder instance
+ */
+JsonBuilder *
+json_builder_end_array (JsonBuilder *builder)
+{
+ JsonBuilderState *state;
+
+ g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
+ g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL);
+ g_return_val_if_fail (json_builder_current_mode (builder) == JSON_BUILDER_MODE_ARRAY, NULL);
+
+ state = g_queue_pop_head (builder->priv->stack);
+
+ if (builder->priv->immutable)
+ json_array_seal (state->data.array);
+
+ if (g_queue_is_empty (builder->priv->stack))
+ {
+ builder->priv->root = json_node_new (JSON_NODE_ARRAY);
+ json_node_take_array (builder->priv->root, json_array_ref (state->data.array));
+
+ if (builder->priv->immutable)
+ json_node_seal (builder->priv->root);
+ }
+
+ json_builder_state_free (state);
+
+ return builder;
+}
+
+/**
+ * json_builder_set_member_name:
+ * @builder: a builder
+ * @member_name: the name of the member
+ *
+ * Sets the name of the member in an object.
+ *
+ * This function must be followed by of these functions:
+ *
+ * - [method(a)Json.Builder.add_value], to add a scalar value to the member
+ * - [method(a)Json.Builder.begin_object], to add an object to the member
+ * - [method(a)Json.Builder.begin_array], to add an array to the member
+ *
+ * This function can only be called within an open object.
+ *
+ * Return value: (nullable) (transfer none): the builder instance
+ */
+JsonBuilder *
+json_builder_set_member_name (JsonBuilder *builder,
+ const gchar *member_name)
+{
+ JsonBuilderState *state;
+
+ g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
+ g_return_val_if_fail (member_name != NULL, NULL);
+ g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL);
+ g_return_val_if_fail (json_builder_current_mode (builder) == JSON_BUILDER_MODE_OBJECT, NULL);
+
+ state = g_queue_peek_head (builder->priv->stack);
+ state->member_name = g_strdup (member_name);
+ state->mode = JSON_BUILDER_MODE_MEMBER;
+
+ return builder;
+}
+
+/**
+ * json_builder_add_value:
+ * @builder: a builder
+ * @node: (transfer full): the value of the member or element
+ *
+ * Adds a value to the currently open object member or array.
+ *
+ * If called after [method(a)Json.Builder.set_member_name], sets the given node
+ * as the value of the current member in the open object; otherwise, the node
+ * is appended to the elements of the open array.
+ *
+ * The builder will take ownership of the node.
+ *
+ * Return value: (nullable) (transfer none): the builder instance
+ */
+JsonBuilder *
+json_builder_add_value (JsonBuilder *builder,
+ JsonNode *node)
+{
+ JsonBuilderState *state;
+
+ g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
+ g_return_val_if_fail (node != NULL, NULL);
+ g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL);
+ g_return_val_if_fail (json_builder_is_valid_add_mode (builder), NULL);
+
+ state = g_queue_peek_head (builder->priv->stack);
+
+ if (builder->priv->immutable)
+ json_node_seal (node);
+
+ switch (state->mode)
+ {
+ case JSON_BUILDER_MODE_MEMBER:
+ json_object_set_member (state->data.object, state->member_name, node);
+ g_free (state->member_name);
+ state->member_name = NULL;
+ state->mode = JSON_BUILDER_MODE_OBJECT;
+ break;
+
+ case JSON_BUILDER_MODE_ARRAY:
+ json_array_add_element (state->data.array, node);
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+
+ return builder;
+}
+
+/**
+ * json_builder_add_int_value:
+ * @builder: a builder
+ * @value: the value of the member or element
+ *
+ * Adds an integer value to the currently open object member or array.
+ *
+ * If called after [method(a)Json.Builder.set_member_name], sets the given value
+ * as the value of the current member in the open object; otherwise, the value
+ * is appended to the elements of the open array.
+ *
+ * See also: [method(a)Json.Builder.add_value]
+ *
+ * Return value: (nullable) (transfer none): the builder instance
+ */
+JsonBuilder *
+json_builder_add_int_value (JsonBuilder *builder,
+ gint64 value)
+{
+ JsonBuilderState *state;
+
+ g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
+ g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL);
+ g_return_val_if_fail (json_builder_is_valid_add_mode (builder), NULL);
+
+ state = g_queue_peek_head (builder->priv->stack);
+ switch (state->mode)
+ {
+ case JSON_BUILDER_MODE_MEMBER:
+ json_object_set_int_member (state->data.object, state->member_name, value);
+ g_free (state->member_name);
+ state->member_name = NULL;
+ state->mode = JSON_BUILDER_MODE_OBJECT;
+ break;
+
+ case JSON_BUILDER_MODE_ARRAY:
+ json_array_add_int_element (state->data.array, value);
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+
+ return builder;
+}
+
+/**
+ * json_builder_add_double_value:
+ * @builder: a builder
+ * @value: the value of the member or element
+ *
+ * Adds a floating point value to the currently open object member or array.
+ *
+ * If called after [method(a)Json.Builder.set_member_name], sets the given value
+ * as the value of the current member in the open object; otherwise, the value
+ * is appended to the elements of the open array.
+ *
+ * See also: [method(a)Json.Builder.add_value]
+ *
+ * Return value: (nullable) (transfer none): the builder instance
+ */
+JsonBuilder *
+json_builder_add_double_value (JsonBuilder *builder,
+ gdouble value)
+{
+ JsonBuilderState *state;
+
+ g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
+ g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL);
+ g_return_val_if_fail (json_builder_is_valid_add_mode (builder), NULL);
+
+ sta@@ Diff output truncated at 100000 characters. @@
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).
Branch: refs/heads/master
Author: Jiřà Techet <techet(a)gmail.com>
Committer: Jiřà Techet <techet(a)gmail.com>
Date: Sun, 26 Jan 2025 20:44:23 UTC
Commit: e3849d8d92c915051b326a36eb0504e8ca2e012b
https://github.com/geany/geany-plugins/commit/e3849d8d92c915051b326a36eb050…
Log Message:
-----------
Add LSP plugin
Modified Paths:
--------------
MAINTAINERS
Makefile.am
README
build/geany-plugins.nsi
build/lsp.m4
configure.ac
lsp/AUTHORS
lsp/COPYING
lsp/ChangeLog
lsp/Makefile.am
lsp/NEWS
lsp/README
lsp/data/Makefile.am
lsp/data/lsp.conf
lsp/deps/Makefile.am
lsp/deps/json-glib/json-array.c
lsp/deps/json-glib/json-builder.c
lsp/deps/json-glib/json-builder.h
lsp/deps/json-glib/json-debug.c
lsp/deps/json-glib/json-debug.h
lsp/deps/json-glib/json-enum-types.c
lsp/deps/json-glib/json-enum-types.h
lsp/deps/json-glib/json-gboxed.c
lsp/deps/json-glib/json-generator.c
lsp/deps/json-glib/json-generator.h
lsp/deps/json-glib/json-glib.h
lsp/deps/json-glib/json-gobject-private.h
lsp/deps/json-glib/json-gobject.c
lsp/deps/json-glib/json-gobject.h
lsp/deps/json-glib/json-gvariant.c
lsp/deps/json-glib/json-gvariant.h
lsp/deps/json-glib/json-node.c
lsp/deps/json-glib/json-object.c
lsp/deps/json-glib/json-parser.c
lsp/deps/json-glib/json-parser.h
lsp/deps/json-glib/json-path.c
lsp/deps/json-glib/json-path.h
lsp/deps/json-glib/json-reader.c
lsp/deps/json-glib/json-reader.h
lsp/deps/json-glib/json-scanner.c
lsp/deps/json-glib/json-scanner.h
lsp/deps/json-glib/json-serializable.c
lsp/deps/json-glib/json-types-private.h
lsp/deps/json-glib/json-types.h
lsp/deps/json-glib/json-utils.c
lsp/deps/json-glib/json-utils.h
lsp/deps/json-glib/json-value.c
lsp/deps/json-glib/json-version-macros.h
lsp/deps/json-glib/json-version.h
lsp/deps/jsonrpc-glib/jsonrpc-client.c
lsp/deps/jsonrpc-glib/jsonrpc-client.h
lsp/deps/jsonrpc-glib/jsonrpc-glib.h
lsp/deps/jsonrpc-glib/jsonrpc-input-stream-private.h
lsp/deps/jsonrpc-glib/jsonrpc-input-stream.c
lsp/deps/jsonrpc-glib/jsonrpc-input-stream.h
lsp/deps/jsonrpc-glib/jsonrpc-marshalers.c
lsp/deps/jsonrpc-glib/jsonrpc-marshalers.h
lsp/deps/jsonrpc-glib/jsonrpc-message.c
lsp/deps/jsonrpc-glib/jsonrpc-message.h
lsp/deps/jsonrpc-glib/jsonrpc-output-stream.c
lsp/deps/jsonrpc-glib/jsonrpc-output-stream.h
lsp/deps/jsonrpc-glib/jsonrpc-server.c
lsp/deps/jsonrpc-glib/jsonrpc-server.h
lsp/deps/jsonrpc-glib/jsonrpc-version-macros.h
lsp/deps/jsonrpc-glib/jsonrpc-version.h
lsp/src/Makefile.am
lsp/src/lsp-autocomplete.c
lsp/src/lsp-autocomplete.h
lsp/src/lsp-code-lens.c
lsp/src/lsp-code-lens.h
lsp/src/lsp-command.c
lsp/src/lsp-command.h
lsp/src/lsp-diagnostics.c
lsp/src/lsp-diagnostics.h
lsp/src/lsp-extension.c
lsp/src/lsp-extension.h
lsp/src/lsp-format.c
lsp/src/lsp-format.h
lsp/src/lsp-goto-anywhere.c
lsp/src/lsp-goto-anywhere.h
lsp/src/lsp-goto-panel.c
lsp/src/lsp-goto-panel.h
lsp/src/lsp-goto.c
lsp/src/lsp-goto.h
lsp/src/lsp-highlight.c
lsp/src/lsp-highlight.h
lsp/src/lsp-hover.c
lsp/src/lsp-hover.h
lsp/src/lsp-log.c
lsp/src/lsp-log.h
lsp/src/lsp-main.c
lsp/src/lsp-progress.c
lsp/src/lsp-progress.h
lsp/src/lsp-rename.c
lsp/src/lsp-rename.h
lsp/src/lsp-rpc.c
lsp/src/lsp-rpc.h
lsp/src/lsp-selection-range.c
lsp/src/lsp-selection-range.h
lsp/src/lsp-semtokens.c
lsp/src/lsp-semtokens.h
lsp/src/lsp-server.c
lsp/src/lsp-server.h
lsp/src/lsp-signature.c
lsp/src/lsp-signature.h
lsp/src/lsp-symbol-kinds.c
lsp/src/lsp-symbol-kinds.h
lsp/src/lsp-symbol-tree.c
lsp/src/lsp-symbol-tree.h
lsp/src/lsp-symbol.c
lsp/src/lsp-symbol.h
lsp/src/lsp-symbols.c
lsp/src/lsp-symbols.h
lsp/src/lsp-sync.c
lsp/src/lsp-sync.h
lsp/src/lsp-utils.c
lsp/src/lsp-utils.h
lsp/src/lsp-workspace-folders.c
lsp/src/lsp-workspace-folders.h
lsp/src/spawn/lspunixinputstream.c
lsp/src/spawn/lspunixinputstream.h
lsp/src/spawn/lspunixoutputstream.c
lsp/src/spawn/lspunixoutputstream.h
lsp/src/spawn/spawn.c
lsp/src/spawn/spawn.h
po/POTFILES.in
po/POTFILES.skip
Modified: MAINTAINERS
7 lines changed, 7 insertions(+), 0 deletions(-)
===================================================================
@@ -194,6 +194,13 @@ M: Frank Lanitz <frank(a)frank.uvena.de>
W: http://plugins.geany.org/lipsum.html
S: Maintained
+lsp
+P: Jiřà Techet <techet(a)gmail.com>
+g: @techee
+M: Jiřà Techet <techet(a)gmail.com>
+W: http://plugins.geany.org/lsp.html
+S: Maintained
+
markdown
P: Matthew Brush <matt(a)geany.org>
g: @codebrainz
Modified: Makefile.am
4 lines changed, 4 insertions(+), 0 deletions(-)
===================================================================
@@ -109,6 +109,10 @@ if ENABLE_LIPSUM
SUBDIRS += lipsum
endif
+if ENABLE_LSP
+SUBDIRS += lsp
+endif
+
if ENABLE_MARKDOWN
SUBDIRS += markdown
endif
Modified: README
1 lines changed, 1 insertions(+), 0 deletions(-)
===================================================================
@@ -71,6 +71,7 @@ Available plugins are:
* ``latex`` -- the LaTeX plugin
* ``lineoperations`` -- simple line functions that can be applied to an open file
* ``lipsum`` -- the Lipsum plugin
+* ``lsp`` -- the LSP plugin
* ``markdown`` -- the Markdown plugin
* ``overview``-- the overview plugin
* ``pairtaghighlighter`` -- the PairTagHighlighter plugin
Modified: build/geany-plugins.nsi
1 lines changed, 1 insertions(+), 0 deletions(-)
===================================================================
@@ -198,6 +198,7 @@ Section Uninstall
Delete "$INSTDIR\lib\geany\keyrecord.dll"
Delete "$INSTDIR\lib\geany\lipsum.dll"
Delete "$INSTDIR\lib\geany\lineoperations.dll"
+ Delete "$INSTDIR\lib\geany\lsp.dll"
Delete "$INSTDIR\lib\geany\overview.dll"
Delete "$INSTDIR\lib\geany\pairtaghighlighter.dll"
Delete "$INSTDIR\lib\geany\pohelper.dll"
Modified: build/lsp.m4
39 lines changed, 39 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,39 @@
+AC_DEFUN([GP_CHECK_LSP],
+[
+ GP_ARG_DISABLE([LSP], [auto])
+
+ JSON_GLIB_PACKAGE_NAME=json-glib-1.0
+ JSON_GLIB_VERSION=1.10
+ JSONRPC_GLIB_PACKAGE_NAME=jsonrpc-glib-1.0
+ JSONRPC_GLIB_VERSION=3.44
+
+ AC_ARG_ENABLE(system-jsonrpc,
+ AC_HELP_STRING([--enable-system-jsonrpc],
+ [Force using system json-glib and jsonrpc-glib libraries for the LSP plugin. [[default=no]]]),,
+ enable_system_jsonrpc=no)
+
+ PKG_CHECK_MODULES([SYSTEM_JSONRPC],
+ [${JSON_GLIB_PACKAGE_NAME} >= ${JSON_GLIB_VERSION}
+ ${JSONRPC_GLIB_PACKAGE_NAME} >= ${JSONRPC_GLIB_VERSION}],
+ have_system_jsonrpc=yes
+ echo "Required system versions of json-glib and jsonrpc-glib found - using them.",
+ have_system_jsonrpc=no
+ echo "Required system versions of json-glib and jsonrpc-glib not found - using builtin versions.")
+
+ AS_IF([test x"$enable_system_jsonrpc" = "xyes" || test x"$have_system_jsonrpc" = "xyes"],
+ [GP_CHECK_PLUGIN_DEPS([LSP], [LSP],
+ [${JSON_GLIB_PACKAGE_NAME} >= ${JSON_GLIB_VERSION}
+ ${JSONRPC_GLIB_PACKAGE_NAME} >= ${JSONRPC_GLIB_VERSION}])],
+ [])
+
+ AM_CONDITIONAL(ENABLE_BUILTIN_JSONRPC, [ test x"$have_system_jsonrpc" = "xno" ])
+
+ GP_COMMIT_PLUGIN_STATUS([LSP])
+
+ AC_CONFIG_FILES([
+ lsp/Makefile
+ lsp/deps/Makefile
+ lsp/src/Makefile
+ lsp/data/Makefile
+ ])
+])
Modified: configure.ac
1 lines changed, 1 insertions(+), 0 deletions(-)
===================================================================
@@ -55,6 +55,7 @@ GP_CHECK_GITCHANGEBAR
GP_CHECK_KEYRECORD
GP_CHECK_LINEOPERATIONS
GP_CHECK_LIPSUM
+GP_CHECK_LSP
GP_CHECK_MARKDOWN
GP_CHECK_OVERVIEW
GP_CHECK_PAIRTAGHIGHLIGHTER
Modified: lsp/AUTHORS
1 lines changed, 1 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1 @@
+Jiřà Techet <techet(a)gmail.com>
Modified: lsp/COPYING
340 lines changed, 340 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
Modified: lsp/ChangeLog
0 lines changed, 0 insertions(+), 0 deletions(-)
===================================================================
No diff available, check online
Modified: lsp/Makefile.am
4 lines changed, 4 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,4 @@
+include $(top_srcdir)/build/vars.auxfiles.mk
+
+SUBDIRS = deps src data
+plugin = lsp
Modified: lsp/NEWS
0 lines changed, 0 insertions(+), 0 deletions(-)
===================================================================
No diff available, check online
Modified: lsp/README
288 lines changed, 288 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,288 @@
+===
+LSP
+===
+
+.. contents::
+
+About
+=====
+
+LSP Client is a language server protocol client plugin that allows to run multiple
+language servers for various programming languages, making their functionality
+accessible to Geany.
+
+Configuration
+=============
+
+The plugin does not come bundled with any language server; these must
+be installed independently of the plugin. For installation and configuration
+instructions, please refer to the documentation of the specific servers you plan
+to use, as some may have specific requirements. Note that many language servers,
+such as ``clangd``, ``pylsp``, and ``gopls``, are often packaged by Linux
+distributions, making them easy to install and use.
+
+You can configure servers and other settings using the User configuration file,
+accessible from::
+
+ Tools->LSP Client->User configuration
+
+This file provides extensive information about all the settings options, so be
+sure to refer to it for more details. The default configuration file comes with
+pre-configured values for several language servers; other servers have to be
+added manually.
+
+By default, the LSP plugin is disabled unless explicitly enabled for a
+project under
+
+::
+
+ Project->Properties->LSP Client
+
+This behavior can be controlled by the first three configuration options in
+the ``[all]`` section of the configuration file.
+
+Language servers are started lazily, meaning they only launch when you switch
+a tab to a file with a filetype that has a corresponding LSP server configured.
+After the initial handshake between the client and server, you can check the
+result under
+
+::
+
+ Tools->LSP Client->Server Initialize Responses
+
+This file also provides information about the capabilities offered by the server;
+for more details, refer to:
+
+https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/
+
+In addition to the User configuration file, you can also create a per-project
+configuration file (which can also be shared by multiple projects). This file
+can be configured under the
+
+::
+
+ Project->Properties->LSP Client
+
+tab.
+
+Furthermore, the plugin offers a range of customizable keybindings, which can be
+configured from::
+
+ Edit->Preferences->Keybindings->LSP Client
+
+Usage
+=====
+
+This section provides an overview of the individual LSP features supported by
+the plugin, along with guidance on how to use them. You can enable or disable
+each feature in the configuration file, where you can also customize certain
+aspects of their behavior.
+
+Please note that not all language servers support every feature. For more
+information on the specific features supported by a language server, consult
+the server's documentation.
+
+Autocompletion
+--------------
+
+Autocompletion works similarly to Geany's autocompletion feature. You can
+configure keybindings triggering the autocompletion popup.
+
+Function signagure
+------------------
+
+When you type an open brace after a function name, the plugin displays the
+function's signature in a popup window similarly to Geany's behavior.
+
+Diagnostic messages
+-------------------
+
+LSP diagnostic messages typically include error messages or warnings from
+compilers, as well as messages from linters. These messages are highlighted in
+the code; the exact style of highlighting can be configured to suit your
+preferences. When you hover over the highlighted part with your mouse cursor,
+a popup window appears, providing additional details about the issue. It is
+also possible to display all diagnostic messages received from the server in
+the message window.
+
+Code actions
+------------
+
+Some servers offer auto-fixes of certain issues or various refactoring options.
+For instance, the ``clangd`` server displays ``fix available`` next to the issue
+in the hover popup window. To perform the auto-fix, right-click the line with
+the issue and select the corresponding option from the Commands submenu. This
+popup can also be invoked by a keybinding.
+
+Code lenses
+-----------
+
+Code lenses are executable commands that are specific to a particular piece of
+code. As Geany's Scintilla component limitations prevent these commands
+from being clickable and executable directly in the editor, they are accessible
+through the Commands submenu of the context menu, similarly to code actions.
+
+Semantic token type highlighting
+--------------------------------
+
+Language servers that provide semantic token support can be used to highlight
+types, such as class names, in the code. You can customize various aspects of
+how the results are visualized in the editor through the configuration file.
+
+Hover popup
+-----------
+
+The language server can be configured to display a popup window with detailed
+information about the symbol under the mouse cursor. However, as this feature
+can be slightly annoying, it is disabled by default. Alternatively, you can
+access this feature through a keybinding.
+
+Symbol tree
+-----------
+
+The LSP symbol tree tab in the sidebar, separate from Geany's Symbols tab,
+shows document symbols in a similar manner to the Geany's symbol tree feature.
+
+Go to symbol definition/declaration
+-----------------------------------
+
+Similarly to Geany, you can navigate to the symbol definition/declaration
+by control-clicking it in the document or by using the corresponding keybinding.
+This feature is also available from the context menu.
+
+Go to type definition
+---------------------
+
+This feature enables quick navigation to the definition of the type associated
+with the symbol under the cursor, such as the type of a variable. You can also
+access this feature from the context menu.
+
+Swap header/source
+------------------
+
+This is a non-standard clangd extension allowing quick swapping between a
+source file and the corresponding header. This feature is not supported by
+any other language server.
+
+Find references
+---------------
+
+This feature finds all references of the symbol under the cursor in the project.
+This feature is also accessible from the context menu.
+
+Find implementations
+--------------------
+
+This feature allows you to locate all classes that implement the interface under
+the cursor.
+
+Navigation to document/project symbols, files, and line numbers
+---------------------------------------------------------------
+
+The plugin provides a simple, VSCode-style panel for navigating your project.
+The
+
+::
+
+ Tools->LSP Client->Go to Anywhere
+
+command offers four types of navigation options:
+
+- Open files by typing their name directly in the entry
+- Navigate to symbols in the current document by prefixing the query with ``@``
+- Navigate to symbols across the entire project by prefixing the query with ``#``
+- Jump to a specific line in the current document by prefixing the query with ``:``
+
+The other related queries in the LSP Client menu (also accessible via a keybinding)
+simply pre-fill the prefix for you, but otherwise function identically.
+
+Code formatting
+---------------
+
+The code formatting feature allows you to format either the entire document or
+a selected portion of code, depending on the LSP server's support for this
+functionality. You can access this feature from the context menu.
+
+Identical symbol highlighting
+-----------------------------
+
+When you click on a symbol in the document, this feature highlights all its
+occurrences in the document. You can customize the highlighting style to your
+preference by configuring it in the configuration file. Also, it is possible
+to disable this feature to be performed automatically, but, instead, manually
+through a keybinding.
+
+Smart selection expanding/shrinking
+-----------------------------------
+
+This feature allows to expand the current text selection to contain the next
+upper syntactic element such as a parent block in programming languages or a
+parent tag in XML. Selection shrinking works in the opposite direction.
+
+Document symbol renaming
+------------------------
+
+This feature leverages the identical symbol highlighting described above to
+select all symbol occurrences, create multiple cursors at their positions in the
+document, and rename them simultaneously as you type. You can also access this
+feature from the context menu.
+
+Project-wide renaming
+---------------------
+
+After selecting Rename in Project from the context menu or the plugin menu,
+you can rename all symbols in the project.
+
+**Warning:** This feature has a potential to modify many files and language
+servers may not be completely reliable when performing the rename so be very
+cautious when using it. The plugin does not perform any additional
+checks and does not show any preview of the changes so it is best to use this
+feature only after committing all modified files so you can
+easily revert to a working state if needed. Since this is potentially a
+dangerous operation, to prevent accidental renames, the "Rename" button in the
+dialog is not selected by defalut and simply pressing enter just cancels the
+dialog.
+
+Limitations
+===========
+
+By design, the plugin communicates over stdin/stdout only, is responsible
+for launching and terminating the language server process, and supports only
+a single language server per file type.
+
+All of these limitations are addressed by the LSP proxy project available at
+https://github.com/techee/lsp-proxy and related issues should be directed there.
+
+License
+=======
+
+Geany LSP Client is distributed under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version. A copy of this license
+can be found in the file COPYING included with the source code of this
+program.
+
+Downloads
+=========
+
+Geany LSP Client can be downloaded from the development repository available
+at https://github.com/techee/geany-lsp/. In addition, it is also distributed
+as part of the combined Geany Plugins release. For more information and
+downloads, please visit https://plugins.geany.org/geany-plugins/
+
+Development Code
+================
+
+Get the code from::
+
+ git clone https://github.com/techee/geany-lsp.git
+
+Ideas, questions, patches and bug reports
+=========================================
+
+Please direct all questions, bug reports and patches to the development
+repository at https://github.com/techee/geany-lsp/ and open the corresponding
+bug report or pull request there.
+
+2023-2024 by Jiřà Techet
+techet(at)gmail(dot)com
Modified: lsp/data/Makefile.am
5 lines changed, 5 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,5 @@
+include $(top_srcdir)/build/vars.docs.mk
+
+plugin = lsp
+
+dist_plugindata_DATA = lsp.conf
Modified: lsp/data/lsp.conf
534 lines changed, 534 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,534 @@
+# The global configuration file, accessible through
+# Tools->LSP Client->Global Configuration, defines default values for various
+# configuration options.
+#
+# When accessing the user configuration file using
+# Tools->LSP Client->User Configuration, a copy of the global configuration file
+# is created in user's configuration directory in which users can override
+# various settings from the global configuration file.
+#
+# In addition, it is possible to create a project-wide configuration file used
+# for a single project or shared by multiple projects whose path can be
+# specified under Project->Properties->LSP Client->Configuration file. When such
+# a file is defined and the project is configured to use the project
+# configuration, this configuration file overrides the global configuration
+# instead of the user configuration file.
+#
+# Each configuration file may contain the [all] section which contains settings
+# common for all language servers, and several filetype-specific sections
+# containing settings specific for the given filetype. The names of these
+# sections are identical to the names defined in
+# Tools->Configuration Files->filetype_extensions.conf; for instance [Python]
+# for the Python programming language (case sensitive). Most of the options can
+# appear both in the [all] section and the filetype-specific sections except for
+# a few that make only sense in the filetype-specific section, like e.g. the
+# 'cmd' option containing the command that starts the server. Any option defined
+# in the filetype-specific section overrides identically named option defined in
+# the [all] section for that particular language server.
+#
+# Not all LSP features are supported by all LSP servers. To learn more about
+# what features are supported by the particular server you are trying to use,
+# you can check the result of the initial client-server handshake by going to
+# Tools->LSP Client->Server Initialize Responses (the server must be running
+# to see any result).
+#
+# All servers are automatically restarted when any of the configuration files
+# changes. Servers are started lazily after a tab is switched to a document for
+# which a server is configured (this means that restart typically means shutdown
+# of all servers after which they are started as needed).
+
+
+[all]
+# Defines whether the plugin should be enabled automatically for new or existing
+# projects (that have not yet been configured to use LSP). This option
+# is only valid in the [all] section
+enable_by_default=false
+# Defines whether the server should be used when no project is open. Servers
+# may not work correctly without a project because most of them need to know
+# the path to the project directory which corresponds to the path defined under
+# Project->Properties->Base path. This option can be partially overridden
+# by project_root_marker_patterns, see below
+use_without_project=false
+# Defines whether the server should be used for files whose path is not within
+# the project directory. This option can be partially overridden by
+# project_root_marker_patterns, see below
+use_outside_project_dir=false
+# A semicolon-separated list of glob patterns of files that are typically stored
+# inside the root directory of the project. Language servers supporting
+# changeNotifications of workspaceFolders (these two values should appear inside
+# the server initialize response) can use these marker files to detect root
+# project directories of open files. Starting from the open file directory,
+# the plugin goes up in the directory structure and tests whether a file
+# matching project_root_marker_patterns exists - if it does, such a directory
+# is considered to be the root directory of the project. This allows to
+# detect projects without any Geany project open and allows the plugin to work
+# on multiple projects simultaneously. Typically, the pattern contains
+# files/directories such as .git, configure.ac, go.mod, etc. If a pattern is
+# found, use_without_project and use_outside_project_dir are ignored
+project_root_marker_patterns=
+# In additon to standard identifier characters a-zA-Z0-9_, this configuration
+# option allows adding extra characters that can appear inside identifiers.
+# For instance $- will add '$' and '-' to the above set.
+extra_identifier_characters=
+# Some servers require that the initialization options configuration is sent
+# using workspace/didChangeConfiguration instead of the initialize request.
+# This option does this right after the initialize request completes.
+send_did_change_configuration=false
+
+# The number of keybindings that can be assigned to LSP code action commands.
+# This option is valid only within the [all] section and changing the value
+# requires either the plugin reload or Geany restart
+command_keybinding_num=5
+# When the keybinding Command 1 is invoked, it checks whether the
+# command_1_regex matches any of the items from the Commands submenu of the
+# context menu. The first matched entry is executed. For convenience, regex
+# matches are case insensitive. Up to command_keybinding_num command keybindings
+# can be specified this way
+command_1_regex=
+# Regex specifying which of the commands present in the context menu under the
+# Commands submenu will be automatically performed on save. If multiple entries
+# match, all of them will be performed. For convenience, regex matches are case
+# insensitive
+command_on_save_regex=
+
+# When the filetype-specific 'rpc_log' settings is defined, this option
+# specifies whether the log should contain all details including method
+# parameters, or just the method name and type of the communication
+rpc_log_full=false
+# Show server's stderr in Geany's stderr (when started from terminal)
+show_server_stderr=false
+# Tracing level of the server (when supported). When enabled, tracing messages
+# are logged into stdout. Valid values are 'off', 'messages', 'verbose'
+trace_value=off
+# Enables or disables telemetry notification logging to stdout
+telemetry_notifications=false
+
+# Whether LSP should be used for autocompletion
+autocomplete_enable=true
+# Servers return the label that can be shown in the autocompletion popup for
+# individual autocompletion entries, or it is possible to use just the text that
+# gets inserted when selecting the entry. See also autocomplete_use_snippets.
+autocomplete_use_label=true
+# Whether snippets should be shown in the autocompletion list. Snippet support
+# is only partial so things may not work as expected. When snippets are enabled,
+# it is recommended to use autocomplete_use_label=true, otherwise snippet
+# tab stops and other snippet information is shown in the autocompletion popup.
+autocomplete_use_snippets=false
+# Maximum number of autocompletion entries shown in the popup window (including
+# those that will only get visible after scrolling the contents)
+autocomplete_window_max_entries=20
+# Maximum number of autocompletion entries shown without scrolling (defining the
+# actual height of the popup)
+autocomplete_window_max_displayed=8
+# The maximum width of the autocompletion popup in displayed characters
+autocomplete_window_max_width=60
+# Whether to automatically apply additional edits defined for the autocompletion
+# entry. These are typically imports of the modules where the inserted symbol is
+# defined
+autocomplete_apply_additional_edits=false
+# Semicolon separated list of character sequences which can trigger
+# autocompletion. Normally, the server defines these but this option can be used
+# to further restrict the list only to some sequences if the server-provided
+# value does not work well (e.g. when server's trigger chars for autocompletion
+# clash with signature trigger chars - Rust server for instance uses '(' for
+# both and omitting '(' in autocomplete sequences shows signature instead)
+autocomplete_trigger_sequences=
+# Semicolon separated list of words that make the autocompletion popup hide.
+# This is useful for instance for languages like Pascal that use keywords
+# 'begin' and 'end' which are typically followed by a newline where typing enter
+# after these words might select some unwanted word from the autocompletion list.
+autocomplete_hide_after_words=
+# Whether to perform autocompletion inside strings
+autocomplete_in_strings=false
+# Show documentation (if available) of selected item in autocompletion popup
+# in Geany status bar
+autocomplete_show_documentation=true
+
+# Whether LSP should be used to display diagnostic messages. Typically these are
+# compiler errors or warnings
+diagnostics_enable=true
+# Semicolon-separated glob patterns specifying files for which diagnostic
+# messages are not shown. Useful when the server has a problem with some files
+diagnostics_disable_for=
+# For the statusbar issue number indicator, consider only issues of the
+# configured severity or highler. Valid values are: 1 (error), 2 (warning),
+# 3 (info), 4 (hint). E.g. setting this value to 2 will show issue number
+# for errors and warnings only.
+diagnostics_statusbar_severity=2
+# Defines the style of error diagnostics - visual style such as underline, and
+# its color. Empty value means that diagnostic messages of the given severity
+# are not displayed.
+# The first number is the "indicator index" of Scintilla - each style should
+# have a unique value from 8 to 31. Can be changed when the value clashes with
+# some other plugin.
+# The remaining values correspond to
+# SCI_INDICSETFORE; SCI_INDICSETALPHA; SCI_INDICSETOUTLINEALPHA; SCI_INDICSETSTYLE
+# - see Scintilla documentation for more information
+diagnostics_error_style=13;#ff3030;70;255;1
+# Defines the style of warning diagnostics
+diagnostics_warning_style=14;#ee00ee;70;255;1
+# Defines the style of information diagnostics
+diagnostics_info_style=15;#909090;70;255;14
+# Defines the style of hint diagnostics
+diagnostics_hint_style=16;#909090;70;255;14
+
+# Whether LSP should be used to show a popup with details when hovering over
+# symbols.
+hover_enable=false
+# Maximum number of lines of the popup window
+hover_popup_max_lines=20
+# Maximum number of paragraphs shown in the popup window
+hover_popup_max_paragraphs=1000
+
+# Whether LSP should be used to show function parameter signatures e.g. after
+# typing '('
+signature_enable=true
+
+# Whether LSP should be used for going to symbol definition/declaration
+goto_enable=true
+
+# Whether LSP should be used for displaying symbols in the sidebar (in a tab
+# separate from normal Geany symbols)
+document_symbols_enable=true
+# The label used for the LSP symbols tab. When left empty, the tab is not
+# displayed. This option is only valid in the [all] section
+document_symbols_tab_label=LSP Symbols
+
+# Whether LSP should be used for highlighting semantic tokens in the editor,
+# such as types. Most servers don't support this feature so disabled by default.
+semantic_tokens_enable=false
+# Always perform "full" semantic token request instead of using "delta"
+# requests. Can be used when servers don't support delta tokens correctly
+semantic_tokens_force_full=false
+# Semicolon-separated list of semantic tokens that should be highlighted as
+# types. For valid values, see
+# https://microsoft.github.io/language-server-protocol/specifications/lsp/3.1…
+semantic_tokens_types=type;class;enum;interface;struct
+# When not empty, Scintilla indicators are used for highlighting semantic
+# token types. See diagnostics_error_style for more details about the valid
+# values. Note that because of Scintilla limitations, this value cannot be bold
+#semantic_tokens_type_style=17;#00007f;255;255;17
+semantic_tokens_type_style=
+# When not using semantic_tokens_type_style, this indicates the index in the
+# Scintilla lexer used for custom keywords. This feature is supported only by
+# some lexers like C/C++ and derived lexers. When using this method, the
+# value can be bold but all the occurrences of the given word in the document
+# is highlighted regardless of the context in which it is used
+semantic_tokens_lexer_kw_index=3
+
+# Whether LSP should be used for highlighting all other uses of a variable under
+# cursor.
+highlighting_enable=true
+# Indicator style used for highlighting - see diagnostics_error_style
+highlighting_style=18;#b0b0b0;90;255;8
+
+# Whether LSP should be used for "code lenses" showing commands available
+# for the given line. After right-clicking the line with the code lens, these
+# commands are available in the Commands submenu.
+code_lens_enable=true
+# Defines the foreground and the background color of the code lens indicator.
+code_lens_style=#000000;#ffffa0
+
+# JSON file containing formatting options defined in
+# https://microsoft.github.io/language-server-protocol/specifications/lsp/3.1…
+# e.g. { "tabSize": 4, "insertSpaces": false }. Supported only by some language
+# servers.
+#formatting_options_file=/home/some_user/my_formatting_config_file.json
+formatting_options_file=
+# Like above but with the JSON placed directly into the value. When both
+# formatting_options_file and formatting_options are specified, the JSON from
+# formatting_options_file is used
+formatting_options={ "tabSize": 4, "insertSpaces": false }
+# Defines whether the LSP code-formatting feature should be auto-performed
+# on every save
+format_on_save=false
+
+# Show progress bar for work in progress server operations. Can be disabled
+# when servers do not correctly terminate progress notifications.
+progress_bar_enable=true
+
+# Enable non-standard clangd extension allowing to swap between C/C++ headers
+# and sources. Only usable for clangd, it does not work with other servers.
+swap_header_source_enable=false
+
+
+# This is a dummy language server configuration describing the available
+# language-specific options. Most of the configuration options from the [all]
+# section can be used here as well.
+# For an extensive list of various servers and their configurations, check
+# https://github.com/neovim/nvim-lspconfig/blob/master/doc/configs.md
+# While the configuration options names of neovim differ from Geany, the
+# general concepts are similar and applicable here.
+[DummyLanguage]
+# The command (including parameters and possibly also the full path) used to
+# start the LSP server. Instead of starting a new server, it is also possible to
+# reuse other language's server using the 'use' option - see the C++
+# configuration
+cmd=srvcmd
+# The server can be started with additional environment variables (such as foo
+# with the value bar, and foo1 with the value bar1 like in the example below).
+env=foo=bar;foo1=bar1
+# File containing initialization options of the server. The server is
+# automatically restarted when this file is modified from within Geany
+initialization_options_file=/home/some_user/init_options.json
+# Like above but with the JSON placed directly into the value. When both
+# initialization_options_file and formatting_options are specified, the JSON
+# from initialization_options_file is used
+initialization_options={"compilationDatabasePath": "/home/some_user/"}
+# When defined, performs logging to the specified file where all RPC
+# communication between the client plugin and the server will be stored (can
+# also be 'stdout' or 'stderr')
+rpc_log=stdout
+# Additional files and their mappings to LSP language IDs for which the server
+# is used as well. The Nth item in the list is always a LSP language ID and the
+# (N+1)th item is a glob pattern defining files for which the language ID is
+# used
+lang_id_mappings=dummylanguage;*.dummy
+
+
+[C]
+# By default, clangd expects compile_commands.json inside the 'build' directory
+# of your project. You can create it using either 'meson setup build' if your
+# project uses meson or e.g. using:
+# mkdir build; bear --output build/compile_commands.json -- make
+# if your project uses some other build tool (you need to install the bear tool
+# first). The compile_commands.json file has to be manually regenerated when
+# the build is modified in any way, such as a file is added/removed.
+cmd=clangd
+swap_header_source_enable=true
+autocomplete_in_strings=true
+autocomplete_use_label=false
+semantic_tokens_enable=true
+#initialization_options={"compilationDatabasePath": "/home/some_user/my_project/my_builddir"}
+formatting_options={ "tabSize": 4, "insertSpaces": false }
+command_1_regex=Apply fix:.*
+#rpc_log=stdout
+#rpc_log_full=true
+#show_server_stderr=true
+
+
+[C++]
+# Don't start a new server but reuse the server defined for some other language
+# instead (C server used for C++ in this case)
+use=C
+
+
+[CSS]
+cmd=vscode-css-language-server --stdio
+extra_identifier_characters=-
+send_did_change_configuration=true
+autocomplete_use_snippets=true
+use_without_project=true
+use_outside_project_dir=true
+#rpc_log=stdout
+#rpc_log_full=true
+#show_server_stderr=true
+
+
+[Dart]
+cmd=dart language-server --protocol=lsp
+# everything except ( which conflicts with signature help
+autocomplete_trigger_sequences=.;=;$;";';{;/;:
+semantic_tokens_enable=true
+#rpc_log=stdout
+#rpc_log_full=true
+#show_server_stderr=true
+
+
+[Go]
+cmd=gopls
+autocomplete_apply_additional_edits=true
+lang_id_mappings=go.mod;go.mod;go.sum;go.sum;gotmpl;*tmpl
+semantic_tokens_enable=true
+semantic_tokens_type_style=17;#00007f;255;255;17
+format_on_save=true
+command_on_save_regex=Organize Imports
+progress_bar_enable=false
+#rpc_log=stdout
+#rpc_log_full=true
+#show_server_stderr=true
+
+
+[Haskell]
+cmd=haskell-language-server-wrapper --lsp
+# Full semantic tokens work but are kind of useless as Scintilla already
+# highlights types
+semantic_tokens_enable=false
+#semantic_tokens_force_full=true
+#initialization_options={"plugin": {"semanticTokens": {"config": { }, "globalOn": true}}}
+#semantic_tokens_type_style=17;#00007f;255;255;17
+#rpc_log=stdout
+#rpc_log_full=true
+#show_server_stderr=true
+
+
+[HTML]
+cmd=vscode-html-language-server --stdio
+extra_identifier_characters=&
+send_did_change_configuration=true
+autocomplete_use_snippets=true
+use_without_project=true
+use_outside_project_dir=true
+#rpc_log=stdout
+#rpc_log_full=true
+#show_server_stderr=true
+
+
+[Java]
+cmd=jdtls
+autocomplete_use_label=false
+#semantic_tokens_enable=true
+#rpc_log=stdout
+#rpc_log_full=true
+#show_server_stderr=true
+
+
+[JSON]
+cmd=vscode-json-languageserver --stdio
+#initialization_options={"provideFormatter": true, "json": { "schemas": [ { "fileMatch": [ "*.json"], "url": "file:///home/parallels/schema.json"}]}}
+send_did_change_configuration=true
+autocomplete_use_snippets=true
+use_without_project=true
+use_outside_project_dir=true
+#formatting_options={ "tabSize": 4, "insertSpaces": true }
+#rpc_log=stdout
+#rpc_log_full=true
+#show_server_stderr=true
+
+
+[LaTeX]
+cmd=texlab
+autocomplete_use_snippets=true
+extra_identifier_characters=:
+use_without_project=true
+use_outside_project_dir=true
+#rpc_log=stdout
+#rpc_log_full=true
+#show_server_stderr=true
+
+
+[Lua]
+cmd=lua-language-server
+autocomplete_use_label=false
+autocomplete_hide_after_words=do;then;true;false;end;else
+use_outside_project_dir=true
+use_without_project=true
+#rpc_log=stdout
+#rpc_log_full=true
+#show_server_stderr=true
+
+
+[Nix]
+cmd=nil
+use_without_project=true
+use_outside_project_dir=true
+extra_identifier_characters=-'
+#rpc_log=stdout
+#rpc_log_full=true
+#show_server_stderr=true
+
+
+[PHP]
+# Note: Server returns highlighting indices off by 1 and highlighting doesn't work
+cmd=phpactor.phar language-server
+autocomplete_trigger_sequences=:;>;$;[;@;';\;\\
+extra_identifier_characters=$
+#rpc_log=stdout
+#rpc_log_full=true
+#show_server_stderr=true
+
+
+[Python]
+# pip install pyright (or: pipx install pyright)
+cmd=pyright-langserver --stdio
+cmd=pyright-langserver --stdio
+# alternatively pylsp, jedi, ruff
+#cmd=pylsp
+#cmd=jedi-language-server
+#cmd=ruff server
+use_outside_project_dir=true
+use_without_project=true
+#rpc_log=stdout
+#rpc_log_full=true
+#show_server_stderr=true
+
+
+[Ruby]
+cmd=solargraph stdio
+#rpc_log=stdout
+#rpc_log_full=true
+#show_server_stderr=true
+
+
+[Rust]
+cmd=rust-analyzer
+semantic_tokens_enable=true
+autocomplete_trigger_sequences=:;.;'
+#rpc_log=stdout
+#rpc_log_full=true
+#show_server_stderr=true
+
+
+[Sh]
+cmd=bash-language-server start
+autocomplete_use_snippets=true
+use_outside_project_dir=true
+use_without_project=true
+#rpc_log=stdout
+#rpc_log_full=true
+#show_server_stderr=true
+
+
+[TypeScript]
+cmd=typescript-language-server --stdio
+semantic_tokens_enable=true
+use_outside_project_dir=true
+use_without_project=true
+#rpc_log=stdout
+#rpc_log_full=true
+#show_server_stderr=true
+
+
+[Javascript]
+use=TypeScript
+
+
+[XML]
+cmd=lemminx
+autocomplete_use_snippets=true
+diagnostics_statusbar_severity=4
+use_without_project=true
+use_outside_project_dir=true
+autocomplete_in_strings=true
+# see https://github.com/eclipse/lemminx/blob/main/docs/Configuration.md
+#initialization_options_file=/home/some_user/init_options.json
+#formatting_options={ "tabSize": 4, "insertSpaces": true }
+#rpc_log=stdout
+#rpc_log_full=true
+#show_server_stderr=true
+
+
+[YAML]
+cmd=yaml-language-server --stdio
+#initialization_options={"yaml": {"schemas": { "/home/parallels/schema.json": "*"}}}
+use_without_project=true
+use_outside_project_dir=true
+#formatting_options={ "tabSize": 4, "insertSpaces": true }
+#rpc_log=stdout
+#rpc_log_full=true
+#show_server_stderr=true
+
+
+[Zig]
+cmd=zls
+semantic_tokens_enable=true
+#autocomplete_use_snippets=true
+#rpc_log=stdout
+#rpc_log_full=true
+#show_server_stderr=true
+
+
+# TODO: help needed! Only the above defined language servers have been tested
+# (lightly). If you know some other working language server or find a problem
+# with the settings above, please open an issue report or a pull request
+# on Github.
Modified: lsp/deps/Makefile.am
78 lines changed, 78 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,78 @@
+include $(top_srcdir)/build/vars.build.mk
+
+noinst_LTLIBRARIES = libjsonrpc.la
+
+json_glib_srcs = \
+ json-glib/json-array.c \
+ json-glib/json-builder.c \
+ json-glib/json-builder.h \
+ json-glib/json-debug.c \
+ json-glib/json-debug.h \
+ json-glib/json-enum-types.c \
+ json-glib/json-enum-types.h \
+ json-glib/json-gboxed.c \
+ json-glib/json-generator.c \
+ json-glib/json-generator.h \
+ json-glib/json-glib.h \
+ json-glib/json-gobject.c \
+ json-glib/json-gobject.h \
+ json-glib/json-gobject-private.h \
+ json-glib/json-gvariant.c \
+ json-glib/json-gvariant.h \
+ json-glib/json-node.c \
+ json-glib/json-object.c \
+ json-glib/json-parser.c \
+ json-glib/json-parser.h \
+ json-glib/json-path.c \
+ json-glib/json-path.h \
+ json-glib/json-reader.c \
+ json-glib/json-reader.h \
+ json-glib/json-scanner.c \
+ json-glib/json-scanner.h \
+ json-glib/json-serializable.c \
+ json-glib/json-types.h \
+ json-glib/json-types-private.h \
+ json-glib/json-utils.c \
+ json-glib/json-utils.h \
+ json-glib/json-value.c \
+ json-glib/json-version.h \
+ json-glib/json-version-macros.h
+
+jsonrpc_glib_srcs = \
+ jsonrpc-glib/jsonrpc-client.c \
+ jsonrpc-glib/jsonrpc-client.h \
+ jsonrpc-glib/jsonrpc-glib.h \
+ jsonrpc-glib/jsonrpc-input-stream.c \
+ jsonrpc-glib/jsonrpc-input-stream.h \
+ jsonrpc-glib/jsonrpc-input-stream-private.h \
+ jsonrpc-glib/jsonrpc-marshalers.c \
+ jsonrpc-glib/jsonrpc-marshalers.h \
+ jsonrpc-glib/jsonrpc-message.c \
+ jsonrpc-glib/jsonrpc-message.h \
+ jsonrpc-glib/jsonrpc-output-stream.c \
+ jsonrpc-glib/jsonrpc-output-stream.h \
+ jsonrpc-glib/jsonrpc-server.c \
+ jsonrpc-glib/jsonrpc-server.h \
+ jsonrpc-glib/jsonrpc-version.h \
+ jsonrpc-glib/jsonrpc-version-macros.h
+
+if ENABLE_BUILTIN_JSONRPC
+
+libjsonrpc_la_SOURCES = \
+ $(json_glib_srcs) \
+ $(jsonrpc_glib_srcs)
+
+libjsonrpc_la_CPPFLAGS = $(AM_CPPFLAGS) \
+ -DG_LOG_DOMAIN=\"LSP\" \
+ -DJSON_COMPILATION \
+ -DJSONRPC_GLIB_COMPILATION \
+ -I$(top_srcdir)/lsp/deps/json-glib \
+ -I$(top_srcdir)/lsp/deps/jsonrpc-glib
+libjsonrpc_la_CFLAGS = $(AM_CFLAGS)
+
+# do not enable cppcheck for json-glib or jsonrpc-glib as it generates lots of
+# false positives and it's not "our" code anyway
+#
+# include $(top_srcdir)/build/cppcheck.mk
+
+endif
Modified: lsp/deps/json-glib/json-array.c
838 lines changed, 838 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,838 @@
+/* json-array.c - JSON array implementation
+ *
+ * This file is part of JSON-GLib
+ * Copyright (C) 2007 OpenedHand Ltd.
+ * Copyright (C) 2009 Intel Corp.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ * Emmanuele Bassi <ebassi(a)linux.intel.com>
+ */
+
+#include "config.h"
+
+#include "json-types-private.h"
+
+/**
+ * JsonArray:
+ *
+ * `JsonArray` is the representation of the array type inside JSON.
+ *
+ * A `JsonArray` contains [struct(a)Json.Node] elements, which may contain
+ * fundamental types, other arrays or objects.
+ *
+ * Since arrays can be arbitrarily big, copying them can be expensive; for
+ * this reason, they are reference counted. You can control the lifetime of
+ * a `JsonArray` using [method(a)Json.Array.ref] and [method(a)Json.Array.unref].
+ *
+ * To append an element, use [method(a)Json.Array.add_element].
+ *
+ * To extract an element at a given index, use [method(a)Json.Array.get_element].
+ *
+ * To retrieve the entire array in list form, use [method(a)Json.Array.get_elements].
+ *
+ * To retrieve the length of the array, use [method(a)Json.Array.get_length].
+ */
+
+G_DEFINE_BOXED_TYPE (JsonArray, json_array, json_array_ref, json_array_unref);
+
+/**
+ * json_array_new: (constructor)
+ *
+ * Creates a new array.
+ *
+ * Return value: (transfer full): the newly created array
+ */
+JsonArray *
+json_array_new (void)
+{
+ JsonArray *array;
+
+ array = g_slice_new0 (JsonArray);
+
+ array->ref_count = 1;
+ array->elements = g_ptr_array_new ();
+
+ return array;
+}
+
+/**
+ * json_array_sized_new: (constructor)
+ * @n_elements: number of slots to pre-allocate
+ *
+ * Creates a new array with `n_elements` slots already allocated.
+ *
+ * Return value: (transfer full): the newly created array
+ */
+JsonArray *
+json_array_sized_new (guint n_elements)
+{
+ JsonArray *array;
+
+ array = g_slice_new0 (JsonArray);
+
+ array->ref_count = 1;
+ array->elements = g_ptr_array_sized_new (n_elements);
+
+ return array;
+}
+
+/**
+ * json_array_ref:
+ * @array: the array to reference
+ *
+ * Acquires a reference on the given array.
+ *
+ * Return value: (transfer none): the passed array, with the reference count
+ * increased by one
+ */
+JsonArray *
+json_array_ref (JsonArray *array)
+{
+ g_return_val_if_fail (array != NULL, NULL);
+ g_return_val_if_fail (array->ref_count > 0, NULL);
+
+ array->ref_count++;
+
+ return array;
+}
+
+/**
+ * json_array_unref:
+ * @array: the array to unreference
+ *
+ * Releases a reference on the given array.
+ *
+ * If the reference count reaches zero, the array is destroyed and all
+ * its allocated resources are freed.
+ */
+void
+json_array_unref (JsonArray *array)
+{
+ g_return_if_fail (array != NULL);
+ g_return_if_fail (array->ref_count > 0);
+
+ if (--array->ref_count == 0)
+ {
+ guint i;
+
+ for (i = 0; i < array->elements->len; i++)
+ json_node_unref (g_ptr_array_index (array->elements, i));
+
+ g_ptr_array_free (array->elements, TRUE);
+ array->elements = NULL;
+
+ g_slice_free (JsonArray, array);
+ }
+}
+
+/**
+ * json_array_seal:
+ * @array: the array to seal
+ *
+ * Seals the given array, making it immutable to further changes.
+ *
+ * This function will recursively seal all elements in the array too.
+ *
+ * If the `array` is already immutable, this is a no-op.
+ *
+ * Since: 1.2
+ */
+void
+json_array_seal (JsonArray *array)
+{
+ guint i;
+
+ g_return_if_fail (array != NULL);
+ g_return_if_fail (array->ref_count > 0);
+
+ if (array->immutable)
+ return;
+
+ /* Propagate to all members. */
+ for (i = 0; i < array->elements->len; i++)
+ json_node_seal (g_ptr_array_index (array->elements, i));
+
+ array->immutable_hash = json_array_hash (array);
+ array->immutable = TRUE;
+}
+
+/**
+ * json_array_is_immutable:
+ * @array: a JSON array
+ *
+ * Check whether the given `array` has been marked as immutable by calling
+ * [method(a)Json.Array.seal] on it.
+ *
+ * Since: 1.2
+ * Returns: %TRUE if the array is immutable
+ */
+gboolean
+json_array_is_immutable (JsonArray *array)
+{
+ g_return_val_if_fail (array != NULL, FALSE);
+ g_return_val_if_fail (array->ref_count > 0, FALSE);
+
+ return array->immutable;
+}
+
+/**
+ * json_array_get_elements:
+ * @array: a JSON array
+ *
+ * Retrieves all the elements of an array as a list of nodes.
+ *
+ * Return value: (element-type JsonNode) (transfer container) (nullable): the elements
+ * of the array
+ */
+GList *
+json_array_get_elements (JsonArray *array)
+{
+ GList *retval;
+ guint i;
+
+ g_return_val_if_fail (array != NULL, NULL);
+
+ retval = NULL;
+ for (i = 0; i < array->elements->len; i++)
+ retval = g_list_prepend (retval,
+ g_ptr_array_index (array->elements, i));
+
+ return g_list_reverse (retval);
+}
+
+/**
+ * json_array_dup_element:
+ * @array: a JSON array
+ * @index_: the index of the element to retrieve
+ *
+ * Retrieves a copy of the element at the given position in the array.
+ *
+ * Return value: (transfer full): a copy of the element at the given position
+ *
+ * Since: 0.6
+ */
+JsonNode *
+json_array_dup_element (JsonArray *array,
+ guint index_)
+{
+ JsonNode *retval;
+
+ g_return_val_if_fail (array != NULL, NULL);
+ g_return_val_if_fail (index_ < array->elements->len, NULL);
+
+ retval = json_array_get_element (array, index_);
+ if (!retval)
+ return NULL;
+
+ return json_node_copy (retval);
+}
+
+/**
+ * json_array_get_element:
+ * @array: a JSON array
+ * @index_: the index of the element to retrieve
+ *
+ * Retrieves the element at the given position in the array.
+ *
+ * Return value: (transfer none): the element at the given position
+ */
+JsonNode *
+json_array_get_element (JsonArray *array,
+ guint index_)
+{
+ g_return_val_if_fail (array != NULL, NULL);
+ g_return_val_if_fail (index_ < array->elements->len, NULL);
+
+ return g_ptr_array_index (array->elements, index_);
+}
+
+/**
+ * json_array_get_int_element:
+ * @array: a JSON array
+ * @index_: the index of the element to retrieve
+ *
+ * Conveniently retrieves the integer value of the element at the given
+ * position inside an array.
+ *
+ * See also: [method(a)Json.Array.get_element], [method(a)Json.Node.get_int]
+ *
+ * Return value: the integer value
+ *
+ * Since: 0.8
+ */
+gint64
+json_array_get_int_element (JsonArray *array,
+ guint index_)
+{
+ JsonNode *node;
+
+ g_return_val_if_fail (array != NULL, 0);
+ g_return_val_if_fail (index_ < array->elements->len, 0);
+
+ node = g_ptr_array_index (array->elements, index_);
+ g_return_val_if_fail (node != NULL, 0);
+ g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE, 0);
+
+ return json_node_get_int (node);
+}
+
+/**
+ * json_array_get_double_element:
+ * @array: a JSON array
+ * @index_: the index of the element to retrieve
+ *
+ * Conveniently retrieves the floating point value of the element at
+ * the given position inside an array.
+ *
+ * See also: [method(a)Json.Array.get_element], [method(a)Json.Node.get_double]
+ *
+ * Return value: the floating point value
+ *
+ * Since: 0.8
+ */
+gdouble
+json_array_get_double_element (JsonArray *array,
+ guint index_)
+{
+ JsonNode *node;
+
+ g_return_val_if_fail (array != NULL, 0.0);
+ g_return_val_if_fail (index_ < array->elements->len, 0.0);
+
+ node = g_ptr_array_index (array->elements, index_);
+ g_return_val_if_fail (node != NULL, 0.0);
+ g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE, 0.0);
+
+ return json_node_get_double (node);
+}
+
+/**
+ * json_array_get_boolean_element:
+ * @array: a JSON array
+ * @index_: the index of the element to retrieve
+ *
+ * Conveniently retrieves the boolean value of the element at the given
+ * position inside an array.
+ *
+ * See also: [method(a)Json.Array.get_element], [method(a)Json.Node.get_boolean]
+ *
+ * Return value: the boolean value
+ *
+ * Since: 0.8
+ */
+gboolean
+json_array_get_boolean_element (JsonArray *array,
+ guint index_)
+{
+ JsonNode *node;
+
+ g_return_val_if_fail (array != NULL, FALSE);
+ g_return_val_if_fail (index_ < array->elements->len, FALSE);
+
+ node = g_ptr_array_index (array->elements, index_);
+ g_return_val_if_fail (node != NULL, FALSE);
+ g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE, FALSE);
+
+ return json_node_get_boolean (node);
+}
+
+/**
+ * json_array_get_string_element:
+ * @array: a JSON array
+ * @index_: the index of the element to retrieve
+ *
+ * Conveniently retrieves the string value of the element at the given
+ * position inside an array.
+ *
+ * See also: [method(a)Json.Array.get_element], [method(a)Json.Node.get_string]
+ *
+ * Return value: (transfer none): the string value
+ *
+ * Since: 0.8
+ */
+const gchar *
+json_array_get_string_element (JsonArray *array,
+ guint index_)
+{
+ JsonNode *node;
+
+ g_return_val_if_fail (array != NULL, NULL);
+ g_return_val_if_fail (index_ < array->elements->len, NULL);
+
+ node = g_ptr_array_index (array->elements, index_);
+ g_return_val_if_fail (node != NULL, NULL);
+ g_return_val_if_fail (JSON_NODE_HOLDS_VALUE (node) || JSON_NODE_HOLDS_NULL (node), NULL);
+
+ if (JSON_NODE_HOLDS_NULL (node))
+ return NULL;
+
+ return json_node_get_string (node);
+}
+
+/**
+ * json_array_get_null_element:
+ * @array: a JSON array
+ * @index_: the index of the element to retrieve
+ *
+ * Conveniently checks whether the element at the given position inside the
+ * array contains a `null` value.
+ *
+ * See also: [method(a)Json.Array.get_element], [method(a)Json.Node.is_null]
+ *
+ * Return value: `TRUE` if the element is `null`
+ *
+ * Since: 0.8
+ */
+gboolean
+json_array_get_null_element (JsonArray *array,
+ guint index_)
+{
+ JsonNode *node;
+
+ g_return_val_if_fail (array != NULL, FALSE);
+ g_return_val_if_fail (index_ < array->elements->len, FALSE);
+
+ node = g_ptr_array_index (array->elements, index_);
+ g_return_val_if_fail (node != NULL, FALSE);
+
+ if (JSON_NODE_HOLDS_NULL (node))
+ return TRUE;
+
+ if (JSON_NODE_HOLDS_ARRAY (node))
+ return json_node_get_array (node) == NULL;
+
+ if (JSON_NODE_HOLDS_OBJECT (node))
+ return json_node_get_object (node) == NULL;
+
+ return FALSE;
+}
+
+/**
+ * json_array_get_array_element:
+ * @array: a JSON array
+ * @index_: the index of the element to retrieve
+ *
+ * Conveniently retrieves the array at the given position inside an array.
+ *
+ * See also: [method(a)Json.Array.get_element], [method(a)Json.Node.get_array]
+ *
+ * Return value: (transfer none): the array
+ *
+ * Since: 0.8
+ */
+JsonArray *
+json_array_get_array_element (JsonArray *array,
+ guint index_)
+{
+ JsonNode *node;
+
+ g_return_val_if_fail (array != NULL, NULL);
+ g_return_val_if_fail (index_ < array->elements->len, NULL);
+
+ node = g_ptr_array_index (array->elements, index_);
+ g_return_val_if_fail (node != NULL, NULL);
+ g_return_val_if_fail (JSON_NODE_HOLDS_ARRAY (node) || JSON_NODE_HOLDS_NULL (node), NULL);
+
+ if (JSON_NODE_HOLDS_NULL (node))
+ return NULL;
+
+ return json_node_get_array (node);
+}
+
+/**
+ * json_array_get_object_element:
+ * @array: a JSON array
+ * @index_: the index of the element to retrieve
+ *
+ * Conveniently retrieves the object at the given position inside an array.
+ *
+ * See also: [method(a)Json.Array.get_element], [method(a)Json.Node.get_object]
+ *
+ * Return value: (transfer none): the object
+ *
+ * Since: 0.8
+ */
+JsonObject *
+json_array_get_object_element (JsonArray *array,
+ guint index_)
+{
+ JsonNode *node;
+
+ g_return_val_if_fail (array != NULL, NULL);
+ g_return_val_if_fail (index_ < array->elements->len, NULL);
+
+ node = g_ptr_array_index (array->elements, index_);
+ g_return_val_if_fail (node != NULL, NULL);
+ g_return_val_if_fail (JSON_NODE_HOLDS_OBJECT (node) || JSON_NODE_HOLDS_NULL (node), NULL);
+
+ if (JSON_NODE_HOLDS_NULL (node))
+ return NULL;
+
+ return json_node_get_object (node);
+}
+
+/**
+ * json_array_get_length:
+ * @array: a JSON array
+ *
+ * Retrieves the length of the given array
+ *
+ * Return value: the length of the array
+ */
+guint
+json_array_get_length (JsonArray *array)
+{
+ g_return_val_if_fail (array != NULL, 0);
+
+ return array->elements->len;
+}
+
+/**
+ * json_array_add_element:
+ * @array: a JSON array
+ * @node: (transfer full): the element to add
+ *
+ * Appends the given `node` inside an array.
+ */
+void
+json_array_add_element (JsonArray *array,
+ JsonNode *node)
+{
+ g_return_if_fail (array != NULL);
+ g_return_if_fail (node != NULL);
+
+ g_ptr_array_add (array->elements, node);
+}
+
+/**
+ * json_array_add_int_element:
+ * @array: a JSON array
+ * @value: the integer value to add
+ *
+ * Conveniently adds the given integer value into an array.
+ *
+ * See also: [method(a)Json.Array.add_element], [method(a)Json.Node.set_int]
+ *
+ * Since: 0.8
+ */
+void
+json_array_add_int_element (JsonArray *array,
+ gint64 value)
+{
+ g_return_if_fail (array != NULL);
+
+ json_array_add_element (array, json_node_init_int (json_node_alloc (), value));
+}
+
+/**
+ * json_array_add_double_element:
+ * @array: a JSON array
+ * @value: the floating point value to add
+ *
+ * Conveniently adds the given floating point value into an array.
+ *
+ * See also: [method(a)Json.Array.add_element], [method(a)Json.Node.set_double]
+ *
+ * Since: 0.8
+ */
+void
+json_array_add_double_element (JsonArray *array,
+ gdouble value)
+{
+ g_return_if_fail (array != NULL);
+
+ json_array_add_element (array, json_node_init_double (json_node_alloc (), value));
+}
+
+/**
+ * json_array_add_boolean_element:
+ * @array: a JSON array
+ * @value: the boolean value to add
+ *
+ * Conveniently adds the given boolean value into an array.
+ *
+ * See also: [method(a)Json.Array.add_element], [method(a)Json.Node.set_boolean]
+ *
+ * Since: 0.8
+ */
+void
+json_array_add_boolean_element (JsonArray *array,
+ gboolean value)
+{
+ g_return_if_fail (array != NULL);
+
+ json_array_add_element (array, json_node_init_boolean (json_node_alloc (), value));
+}
+
+/**
+ * json_array_add_string_element:
+ * @array: a JSON array
+ * @value: the string value to add
+ *
+ * Conveniently adds the given string value into an array.
+ *
+ * See also: [method(a)Json.Array.add_element], [method(a)Json.Node.set_string]
+ *
+ * Since: 0.8
+ */
+void
+json_array_add_string_element (JsonArray *array,
+ const gchar *value)
+{
+ JsonNode *node;
+
+ g_return_if_fail (array != NULL);
+
+ node = json_node_alloc ();
+
+ if (value != NULL)
+ json_node_init_string (node, value);
+ else
+ json_node_init_null (node);
+
+ json_array_add_element (array, node);
+}
+
+/**
+ * json_array_add_null_element:
+ * @array: a JSON array
+ *
+ * Conveniently adds a `null` element into an array
+ *
+ * See also: [method(a)Json.Array.add_element], `JSON_NODE_NULL`
+ *
+ * Since: 0.8
+ */
+void
+json_array_add_null_element (JsonArray *array)
+{
+ g_return_if_fail (array != NULL);
+
+ json_array_add_element (array, json_node_init_null (json_node_alloc ()));
+}
+
+/**
+ * json_array_add_array_element:
+ * @array: a JSON array
+ * @value: (nullable) (transfer full): the array to add
+ *
+ * Conveniently adds an array element into an array.
+ *
+ * If `value` is `NULL`, a `null` element will be added instead.
+ *
+ * See also: [method(a)Json.Array.add_element], [method(a)Json.Node.take_array]
+ *
+ * Since: 0.8
+ */
+void
+json_array_add_array_element (JsonArray *array,
+ JsonArray *value)
+{
+ JsonNode *node;
+
+ g_return_if_fail (array != NULL);
+
+ node = json_node_alloc ();
+
+ if (value != NULL)
+ {
+ json_node_init_array (node, value);
+ json_array_unref (value);
+ }
+ else
+ json_node_init_null (node);
+
+ json_array_add_element (array, node);
+}
+
+/**
+ * json_array_add_object_element:
+ * @array: a JSON array
+ * @value: (transfer full) (nullable): the object to add
+ *
+ * Conveniently adds an object into an array.
+ *
+ * If `value` is `NULL`, a `null` element will be added instead.
+ *
+ * See also: [method(a)Json.Array.add_element], [method(a)Json.Node.take_object]
+ *
+ * Since: 0.8
+ */
+void
+json_array_add_object_element (JsonArray *array,
+ JsonObject *value)
+{
+ JsonNode *node;
+
+ g_return_if_fail (array != NULL);
+
+ node = json_node_alloc ();
+
+ if (value != NULL)
+ {
+ json_node_init_object (node, value);
+ json_object_unref (value);
+ }
+ else
+ json_node_init_null (node);
+
+ json_array_add_element (array, node);
+}
+
+/**
+ * json_array_remove_element:
+ * @array: a JSON array
+ * @index_: the position of the element to be removed
+ *
+ * Removes the element at the given position inside an array.
+ *
+ * This function will release the reference held on the element.
+ */
+void
+json_array_remove_element (JsonArray *array,
+ guint index_)
+{
+ g_return_if_fail (array != NULL);
+ g_return_if_fail (index_ < array->elements->len);
+
+ json_node_unref (g_ptr_array_remove_index (array->elements, index_));
+}
+
+/**
+ * json_array_foreach_element:
+ * @array: a JSON array
+ * @func: (scope call): the function to be called on each element
+ * @data: (closure): data to be passed to the function
+ *
+ * Iterates over all elements of an array, and calls a function on
+ * each one of them.
+ *
+ * It is safe to change the value of an element of the array while
+ * iterating over it, but it is not safe to add or remove elements
+ * from the array.
+ *
+ * Since: 0.8
+ */
+void
+json_array_foreach_element (JsonArray *array,
+ JsonArrayForeach func,
+ gpointer data)
+{
+ g_return_if_fail (array != NULL);
+ g_return_if_fail (func != NULL);
+
+ for (guint i = 0; i < array->elements->len; i++)
+ {
+ JsonNode *element_node;
+
+ element_node = g_ptr_array_index (array->elements, i);
+
+ (* func) (array, i, element_node, data);
+ }
+}
+
+/**
+ * json_array_hash:
+ * @key: (type JsonArray) (not nullable): a JSON array to hash
+ *
+ * Calculates a hash value for the given `key`.
+ *
+ * The hash is calculated over the array and all its elements, recursively.
+ *
+ * If the array is immutable, this is a fast operation; otherwise, it scales
+ * proportionally with the length of the array.
+ *
+ * Returns: hash value for the key
+ * Since: 1.2
+ */
+guint
+json_array_hash (gconstpointer key)
+{
+ JsonArray *array; /* unowned */
+ guint hash = 0;
+ guint i;
+
+ g_return_val_if_fail (key != NULL, 0);
+
+ array = (JsonArray *) key;
+
+ /* If the array is immutable, we can use the calculated hash. */
+ if (array->immutable)
+ return array->immutable_hash;
+
+ /* Otherwise, calculate the hash. */
+ for (i = 0; i < array->elements->len; i++)
+ {
+ JsonNode *node = g_ptr_array_index (array->elements, i);
+ hash ^= (i ^ json_node_hash (node));
+ }
+
+ return hash;
+}
+
+/**
+ * json_array_equal:
+ * @a: (type JsonArray) (not nullable): a JSON array
+ * @b: (type JsonArray) (not nullable): another JSON array
+ *
+ * Check whether two arrays are equal.
+ *
+ * Equality is defined as:
+ *
+ * - the array have the same number of elements
+ * - the values of elements in corresponding positions are equal
+ *
+ * Returns: `TRUE` if the arrays are equal, and `FALSE` otherwise
+ * Since: 1.2
+ */
+gboolean
+json_array_equal (gconstpointer a,
+ gconstpointer b)
+{
+ JsonArray *array_a, *array_b; /* unowned */
+ guint length_a, length_b, i;
+
+ g_return_val_if_fail (a != NULL, FALSE);
+ g_return_val_if_fail (b != NULL, FALSE);
+
+ array_a = (JsonArray *) a;
+ array_b = (JsonArray *) b;
+
+ /* Identity comparison. */
+ if (array_a == array_b)
+ return TRUE;
+
+ /* Check lengths. */
+ length_a = json_array_get_length (array_a);
+ length_b = json_array_get_length (array_b);
+
+ if (length_a != length_b)
+ return FALSE;
+
+ /* Check elements. */
+ for (i = 0; i < length_a; i++)
+ {
+ JsonNode *child_a, *child_b; /* unowned */
+
+ child_a = json_array_get_element (array_a, i);
+ child_b = json_array_get_element (array_b, i);
+
+ if (!json_node_equal (child_a, child_b))
+ return FALSE;
+ }
+
+ return TRUE;
+}
Modified: lsp/deps/json-glib/json-builder.c
845 lines changed, 845 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,845 @@
+/* json-generator.c - JSON tree builder
+ *
+ * This file is part of JSON-GLib
+ * Copyright (C) 2010 Luca Bruno <lethalman88(a)gmail.com>
+ * Copyright (C) 2015 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ * Luca Bruno <lethalman88(a)gmail.com>
+ * Philip Withnall <philip.withnall(a)collabora.co.uk>
+ */
+
+/**
+ * JsonBuilder:
+ *
+ * `JsonBuilder` provides an object for generating a JSON tree.
+ *
+ * The root of the JSON tree can be either a [struct(a)Json.Object] or a [struct(a)Json.Array].
+ * Thus the first call must necessarily be either
+ * [method(a)Json.Builder.begin_object] or [method(a)Json.Builder.begin_array].
+ *
+ * For convenience to language bindings, most `JsonBuilder` method return the
+ * instance, making it easy to chain function calls.
+ *
+ * ## Using `JsonBuilder`
+ *
+ * ```c
+ * g_autoptr(JsonBuilder) builder = json_builder_new ();
+ *
+ * json_builder_begin_object (builder);
+ *
+ * json_builder_set_member_name (builder, "url");
+ * json_builder_add_string_value (builder, "http://www.gnome.org/img/flash/two-thirty.png");
+ *
+ * json_builder_set_member_name (builder, "size");
+ * json_builder_begin_array (builder);
+ * json_builder_add_int_value (builder, 652);
+ * json_builder_add_int_value (builder, 242);
+ * json_builder_end_array (builder);
+ *
+ * json_builder_end_object (builder);
+ *
+ * g_autoptr(JsonNode) root = json_builder_get_root (builder);
+ *
+ * g_autoptr(JsonGenerator) gen = json_generator_new ();
+ * json_generator_set_root (gen, root);
+ * g_autofree char *str = json_generator_to_data (gen, NULL);
+ *
+ * // str now contains the following JSON data
+ * // { "url" : "http://www.gnome.org/img/flash/two-thirty.png", "size" : [ 652, 242 ] }
+ * ```
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "json-types-private.h"
+
+#include "json-builder.h"
+
+struct _JsonBuilderPrivate
+{
+ GQueue *stack;
+ JsonNode *root;
+ gboolean immutable;
+};
+
+enum
+{
+ PROP_IMMUTABLE = 1,
+ PROP_LAST
+};
+
+static GParamSpec *builder_props[PROP_LAST] = { NULL, };
+
+typedef enum
+{
+ JSON_BUILDER_MODE_OBJECT,
+ JSON_BUILDER_MODE_ARRAY,
+ JSON_BUILDER_MODE_MEMBER
+} JsonBuilderMode;
+
+typedef struct
+{
+ JsonBuilderMode mode;
+
+ union
+ {
+ JsonObject *object;
+ JsonArray *array;
+ } data;
+ gchar *member_name;
+} JsonBuilderState;
+
+static void
+json_builder_state_free (JsonBuilderState *state)
+{
+ if (G_LIKELY (state))
+ {
+ switch (state->mode)
+ {
+ case JSON_BUILDER_MODE_OBJECT:
+ case JSON_BUILDER_MODE_MEMBER:
+ json_object_unref (state->data.object);
+ g_free (state->member_name);
+ state->data.object = NULL;
+ state->member_name = NULL;
+ break;
+
+ case JSON_BUILDER_MODE_ARRAY:
+ json_array_unref (state->data.array);
+ state->data.array = NULL;
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+
+ g_slice_free (JsonBuilderState, state);
+ }
+}
+
+G_DEFINE_TYPE_WITH_PRIVATE (JsonBuilder, json_builder, G_TYPE_OBJECT)
+
+static void
+json_builder_free_all_state (JsonBuilder *builder)
+{
+ JsonBuilderState *state;
+
+ while (!g_queue_is_empty (builder->priv->stack))
+ {
+ state = g_queue_pop_head (builder->priv->stack);
+ json_builder_state_free (state);
+ }
+
+ if (builder->priv->root)
+ {
+ json_node_unref (builder->priv->root);
+ builder->priv->root = NULL;
+ }
+}
+
+static void
+json_builder_finalize (GObject *gobject)
+{
+ JsonBuilderPrivate *priv = json_builder_get_instance_private ((JsonBuilder *) gobject);
+
+ json_builder_free_all_state (JSON_BUILDER (gobject));
+
+ g_queue_free (priv->stack);
+ priv->stack = NULL;
+
+ G_OBJECT_CLASS (json_builder_parent_class)->finalize (gobject);
+}
+
+static void
+json_builder_set_property (GObject *gobject,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ JsonBuilderPrivate *priv = JSON_BUILDER (gobject)->priv;
+
+ switch (prop_id)
+ {
+ case PROP_IMMUTABLE:
+ /* Construct-only. */
+ priv->immutable = g_value_get_boolean (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+json_builder_get_property (GObject *gobject,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ JsonBuilderPrivate *priv = JSON_BUILDER (gobject)->priv;
+
+ switch (prop_id)
+ {
+ case PROP_IMMUTABLE:
+ g_value_set_boolean (value, priv->immutable);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+json_builder_class_init (JsonBuilderClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ /**
+ * JsonBuilder:immutable:
+ *
+ * Whether the tree should be immutable when created.
+ *
+ * Making the output immutable on creation avoids the expense
+ * of traversing it to make it immutable later.
+ *
+ * Since: 1.2
+ */
+ builder_props[PROP_IMMUTABLE] =
+ g_param_spec_boolean ("immutable",
+ "Immutable Output",
+ "Whether the builder output is immutable.",
+ FALSE,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
+
+ gobject_class->set_property = json_builder_set_property;
+ gobject_class->get_property = json_builder_get_property;
+ gobject_class->finalize = json_builder_finalize;
+
+ g_object_class_install_properties (gobject_class, PROP_LAST, builder_props);
+}
+
+static void
+json_builder_init (JsonBuilder *builder)
+{
+ JsonBuilderPrivate *priv = json_builder_get_instance_private (builder);
+
+ builder->priv = priv;
+
+ priv->stack = g_queue_new ();
+ priv->root = NULL;
+}
+
+static inline JsonBuilderMode
+json_builder_current_mode (JsonBuilder *builder)
+{
+ JsonBuilderState *state = g_queue_peek_head (builder->priv->stack);
+ return state->mode;
+}
+
+static inline gboolean
+json_builder_is_valid_add_mode (JsonBuilder *builder)
+{
+ JsonBuilderMode mode = json_builder_current_mode (builder);
+ return mode == JSON_BUILDER_MODE_MEMBER || mode == JSON_BUILDER_MODE_ARRAY;
+}
+
+/**
+ * json_builder_new:
+ *
+ * Creates a new `JsonBuilder`.
+ *
+ * You can use this object to generate a JSON tree and obtain the root node.
+ *
+ * Return value: the newly created builder instance
+ */
+JsonBuilder *
+json_builder_new (void)
+{
+ return g_object_new (JSON_TYPE_BUILDER, NULL);
+}
+
+/**
+ * json_builder_new_immutable: (constructor)
+ *
+ * Creates a new, immutable `JsonBuilder` instance.
+ *
+ * It is equivalent to setting the [property@Json.Builder:immutable] property
+ * set to `TRUE` at construction time.
+ *
+ * Since: 1.2
+ * Returns: (transfer full): the newly create builder instance
+ */
+JsonBuilder *
+json_builder_new_immutable (void)
+{
+ return g_object_new (JSON_TYPE_BUILDER, "immutable", TRUE, NULL);
+}
+
+/**
+ * json_builder_get_root:
+ * @builder: a builder
+ *
+ * Returns the root of the currently constructed tree.
+ *
+ * if the build is incomplete (ie: if there are any opened objects, or any
+ * open object members and array elements) then this function will return
+ * `NULL`.
+ *
+ * Return value: (nullable) (transfer full): the root node
+ */
+JsonNode *
+json_builder_get_root (JsonBuilder *builder)
+{
+ JsonNode *root = NULL;
+
+ g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
+
+ if (builder->priv->root)
+ root = json_node_copy (builder->priv->root);
+
+ /* Sanity check. */
+ g_assert (!builder->priv->immutable ||
+ root == NULL ||
+ json_node_is_immutable (root));
+
+ return root;
+}
+
+/**
+ * json_builder_reset:
+ * @builder: a builder
+ *
+ * Resets the state of the builder back to its initial state.
+ */
+void
+json_builder_reset (JsonBuilder *builder)
+{
+ g_return_if_fail (JSON_IS_BUILDER (builder));
+
+ json_builder_free_all_state (builder);
+}
+
+/**
+ * json_builder_begin_object:
+ * @builder: a builder
+ *
+ * Opens an object inside the given builder.
+ *
+ * You can add a new member to the object by using [method(a)Json.Builder.set_member_name],
+ * followed by [method(a)Json.Builder.add_value].
+ *
+ * Once you added all members to the object, you must call [method(a)Json.Builder.end_object]
+ * to close the object.
+ *
+ * If the builder is in an inconsistent state, this function will return `NULL`.
+ *
+ * Return value: (nullable) (transfer none): the builder instance
+ */
+JsonBuilder *
+json_builder_begin_object (JsonBuilder *builder)
+{
+ JsonObject *object;
+ JsonBuilderState *state;
+ JsonBuilderState *cur_state;
+
+ g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
+ g_return_val_if_fail (builder->priv->root == NULL, NULL);
+ g_return_val_if_fail (g_queue_is_empty (builder->priv->stack) || json_builder_is_valid_add_mode (builder), NULL);
+
+ object = json_object_new ();
+ cur_state = g_queue_peek_head (builder->priv->stack);
+ if (cur_state)
+ {
+ switch (cur_state->mode)
+ {
+ case JSON_BUILDER_MODE_ARRAY:
+ json_array_add_object_element (cur_state->data.array, json_object_ref (object));
+ break;
+
+ case JSON_BUILDER_MODE_MEMBER:
+ json_object_set_object_member (cur_state->data.object, cur_state->member_name, json_object_ref (object));
+ g_free (cur_state->member_name);
+ cur_state->member_name = NULL;
+ cur_state->mode = JSON_BUILDER_MODE_OBJECT;
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+ }
+
+ state = g_slice_new (JsonBuilderState);
+ state->data.object = object;
+ state->member_name = NULL;
+ state->mode = JSON_BUILDER_MODE_OBJECT;
+ g_queue_push_head (builder->priv->stack, state);
+
+ return builder;
+}
+
+/**
+ * json_builder_end_object:
+ * @builder: a builder
+ *
+ * Closes the object inside the given builder that was opened by the most
+ * recent call to [method(a)Json.Builder.begin_object].
+ *
+ * This function cannot be called after [method(a)Json.Builder.set_member_name].
+ *
+ * Return value: (nullable) (transfer none): the builder instance
+ */
+JsonBuilder *
+json_builder_end_object (JsonBuilder *builder)
+{
+ JsonBuilderState *state;
+
+ g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
+ g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL);
+ g_return_val_if_fail (json_builder_current_mode (builder) == JSON_BUILDER_MODE_OBJECT, NULL);
+
+ state = g_queue_pop_head (builder->priv->stack);
+
+ if (builder->priv->immutable)
+ json_object_seal (state->data.object);
+
+ if (g_queue_is_empty (builder->priv->stack))
+ {
+ builder->priv->root = json_node_new (JSON_NODE_OBJECT);
+ json_node_take_object (builder->priv->root, json_object_ref (state->data.object));
+
+ if (builder->priv->immutable)
+ json_node_seal (builder->priv->root);
+ }
+
+ json_builder_state_free (state);
+
+ return builder;
+}
+
+/**
+ * json_builder_begin_array:
+ * @builder: a builder
+ *
+ * Opens an array inside the given builder.
+ *
+ * You can add a new element to the array by using [method(a)Json.Builder.add_value].
+ *
+ * Once you added all elements to the array, you must call
+ * [method(a)Json.Builder.end_array] to close the array.
+ *
+ * Return value: (nullable) (transfer none): the builder instance
+ */
+JsonBuilder *
+json_builder_begin_array (JsonBuilder *builder)
+{
+ JsonArray *array;
+ JsonBuilderState *state;
+ JsonBuilderState *cur_state;
+
+ g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
+ g_return_val_if_fail (builder->priv->root == NULL, NULL);
+ g_return_val_if_fail (g_queue_is_empty (builder->priv->stack) || json_builder_is_valid_add_mode (builder), NULL);
+
+ array = json_array_new ();
+ cur_state = g_queue_peek_head (builder->priv->stack);
+ if (cur_state)
+ {
+ switch (cur_state->mode)
+ {
+ case JSON_BUILDER_MODE_ARRAY:
+ json_array_add_array_element (cur_state->data.array, json_array_ref (array));
+ break;
+
+ case JSON_BUILDER_MODE_MEMBER:
+ json_object_set_array_member (cur_state->data.object, cur_state->member_name, json_array_ref (array));
+ g_free (cur_state->member_name);
+ cur_state->member_name = NULL;
+ cur_state->mode = JSON_BUILDER_MODE_OBJECT;
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+ }
+
+ state = g_slice_new (JsonBuilderState);
+ state->data.array = array;
+ state->mode = JSON_BUILDER_MODE_ARRAY;
+ g_queue_push_head (builder->priv->stack, state);
+
+ return builder;
+}
+
+/**
+ * json_builder_end_array:
+ * @builder: a builder
+ *
+ * Closes the array inside the given builder that was opened by the most
+ * recent call to [method(a)Json.Builder.begin_array].
+ *
+ * This function cannot be called after [method(a)Json.Builder.set_member_name].
+ *
+ * Return value: (nullable) (transfer none): the builder instance
+ */
+JsonBuilder *
+json_builder_end_array (JsonBuilder *builder)
+{
+ JsonBuilderState *state;
+
+ g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
+ g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL);
+ g_return_val_if_fail (json_builder_current_mode (builder) == JSON_BUILDER_MODE_ARRAY, NULL);
+
+ state = g_queue_pop_head (builder->priv->stack);
+
+ if (builder->priv->immutable)
+ json_array_seal (state->data.array);
+
+ if (g_queue_is_empty (builder->priv->stack))
+ {
+ builder->priv->root = json_node_new (JSON_NODE_ARRAY);
+ json_node_take_array (builder->priv->root, json_array_ref (state->data.array));
+
+ if (builder->priv->immutable)
+ json_node_seal (builder->priv->root);
+ }
+
+ json_builder_state_free (state);
+
+ return builder;
+}
+
+/**
+ * json_builder_set_member_name:
+ * @builder: a builder
+ * @member_name: the name of the member
+ *
+ * Sets the name of the member in an object.
+ *
+ * This function must be followed by of these functions:
+ *
+ * - [method(a)Json.Builder.add_value], to add a scalar value to the member
+ * - [method(a)Json.Builder.begin_object], to add an object to the member
+ * - [method(a)Json.Builder.begin_array], to add an array to the member
+ *
+ * This function can only be called within an open object.
+ *
+ * Return value: (nullable) (transfer none): the builder instance
+ */
+JsonBuilder *
+json_builder_set_member_name (JsonBuilder *builder,
+ const gchar *member_name)
+{
+ JsonBuilderState *state;
+
+ g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
+ g_return_val_if_fail (member_name != NULL, NULL);
+ g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL);
+ g_return_val_if_fail (json_builder_current_mode (builder) == JSON_BUILDER_MODE_OBJECT, NULL);
+
+ state = g_queue_peek_head (builder->priv->stack);
+ state->member_name = g_strdup (member_name);
+ state->mode = JSON_BUILDER_MODE_MEMBER;
+
+ return builder;
+}
+
+/**
+ * json_builder_add_value:
+ * @builder: a builder
+ * @node: (transfer full): the value of the member or element
+ *
+ * Adds a value to the currently open object member or array.
+ *
+ * If called after [method(a)Json.Builder.set_member_name], sets the given node
+ * as the value of the current member in the open object; otherwise, the node
+ * is appended to the elements of the open array.
+ *
+ * The builder will take ownership of the node.
+ *
+ * Return value: (nullable) (transfer none): the builder instance
+ */
+JsonBuilder *
+json_builder_add_value (JsonBuilder *builder,
+ JsonNode *node)
+{
+ JsonBuilderState *state;
+
+ g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
+ g_return_val_if_fail (node != NULL, NULL);
+ g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL);
+ g_return_val_if_fail (json_builder_is_valid_add_mode (builder), NULL);
+
+ state = g_queue_peek_head (builder->priv->stack);
+
+ if (builder->priv->immutable)
+ json_node_seal (node);
+
+ switch (state->mode)
+ {
+ case JSON_BUILDER_MODE_MEMBER:
+ json_object_set_member (state->data.object, state->member_name, node);
+ g_free (state->member_name);
+ state->member_name = NULL;
+ state->mode = JSON_BUILDER_MODE_OBJECT;
+ break;
+
+ case JSON_BUILDER_MODE_ARRAY:
+ json_array_add_element (state->data.array, node);
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+
+ return builder;
+}
+
+/**
+ * json_builder_add_int_value:
+ * @builder: a builder
+ * @value: the value of the member or element
+ *
+ * Adds an integer value to the currently open object member or array.
+ *
+ * If called after [method(a)Json.Builder.set_member_name], sets the given value
+ * as the value of the current member in the open object; otherwise, the value
+ * is appended to the elements of the open array.
+ *
+ * See also: [method(a)Json.Builder.add_value]
+ *
+ * Return value: (nullable) (transfer none): the builder instance
+ */
+JsonBuilder *
+json_builder_add_int_value (JsonBuilder *builder,
+ gint64 value)
+{
+ JsonBuilderState *state;
+
+ g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
+ g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL);
+ g_return_val_if_fail (json_builder_is_valid_add_mode (builder), NULL);
+
+ state = g_queue_peek_head (builder->priv->stack);
+ switch (state->mode)
+ {
+ case JSON_BUILDER_MODE_MEMBER:
+ json_object_set_int_member (state->data.object, state->member_name, value);
+ g_free (state->member_name);
+ state->member_name = NULL;
+ state->mode = JSON_BUILDER_MODE_OBJECT;
+ break;
+
+ case JSON_BUILDER_MODE_ARRAY:
+ json_array_add_int_element (state->data.array, value);
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+
+ return builder;
+}
+
+/**
+ * json_builder_add_double_value:
+ * @builder: a builder
+ * @value: the value of the member or element
+ *
+ * Adds a floating point value to the currently open object member or array.
+ *
+ * If called after [method(a)Json.Builder.set_member_name], sets the given value
+ * as the value of the current member in the open object; otherwise, the value
+ * is appended to the elements of the open array.
+ *
+ * See also: [method(a)Json.Builder.add_value]
+ *
+ * Return value: (nullable) (transfer none): the builder instance
+ */
+JsonBuilder *
+json_builder_add_double_value (JsonBuilder *builder,
+ gdouble value)
+{
+ JsonBuilderState *state;
+
+ g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
+ g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL);
+ g_return_val_if_fail (json_builder_is_valid_add_mode (builder), NULL);
+
+ sta@@ Diff output truncated at 100000 characters. @@
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).
Branch: refs/heads/master
Author: Jiřà Techet <techet(a)gmail.com>
Committer: Jiřà Techet <techet(a)gmail.com>
Date: Wed, 11 Dec 2024 14:21:24 UTC
Commit: 91cc097de2a3eb928b1ad3335bba728da17b14b3
https://github.com/geany/geany-plugins/commit/91cc097de2a3eb928b1ad3335bba7…
Log Message:
-----------
projectorganizer: Create a copy of GeanyWrapLabel and use it for preferences
The explanation string in preferences is long, separated by \n which
makes things hard for translators and makes the dialog wide under some
locales.
Since GeanyWrapLabel is not exported by Geany to plugins, create its local
copy (and rename it to be sure that it doesn't clash with anything).
Modified Paths:
--------------
projectorganizer/src/Makefile.am
projectorganizer/src/prjorg-project.c
projectorganizer/src/prjorg-wraplabel.c
projectorganizer/src/prjorg-wraplabel.h
Modified: projectorganizer/src/Makefile.am
4 lines changed, 3 insertions(+), 1 deletions(-)
===================================================================
@@ -16,7 +16,9 @@ projectorganizer_la_SOURCES = \
prjorg-goto-panel.h \
prjorg-goto-panel.c \
prjorg-goto-anywhere.h \
- prjorg-goto-anywhere.c
+ prjorg-goto-anywhere.c \
+ prjorg-wraplabel.h \
+ prjorg-wraplabel.c
projectorganizer_la_CPPFLAGS = $(AM_CPPFLAGS) \
-DG_LOG_DOMAIN=\"ProjectOrganizer\"
Modified: projectorganizer/src/prjorg-project.c
7 lines changed, 4 insertions(+), 3 deletions(-)
===================================================================
@@ -28,6 +28,7 @@
#include "prjorg-utils.h"
#include "prjorg-project.h"
#include "prjorg-sidebar.h"
+#include "prjorg-wraplabel.h"
extern GeanyPlugin *geany_plugin;
extern GeanyData *geany_data;
@@ -736,10 +737,10 @@ GtkWidget *prjorg_project_add_properties_tab(GtkWidget *notebook)
gtk_box_pack_start(GTK_BOX(vbox), table_box, FALSE, FALSE, 6);
hbox1 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
- label = gtk_label_new(_("The patterns above affect only sidebar and indexing and are not used in the Find in Files\n"
- "dialog. You can further restrict the files belonging to the project by setting the\n"
+ label = prjorg_wrap_label_new(_("The patterns above affect only sidebar and indexing and are not used in the Find in Files "
+ "dialog. You can further restrict the files belonging to the project by setting the"
"File Patterns under the Project tab (these are also used for the Find in Files dialog)."));
- gtk_box_pack_start(GTK_BOX(hbox1), label, FALSE, FALSE, 12);
+ gtk_box_pack_start(GTK_BOX(hbox1), label, TRUE, TRUE, 12);
gtk_box_pack_start(GTK_BOX(vbox), hbox1, FALSE, FALSE, 0);
hbox1 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
Modified: projectorganizer/src/prjorg-wraplabel.c
212 lines changed, 212 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,212 @@
+/*
+ * prjorg-wraplabel.c - renamed copy of geanywraplabel.c from Geany
+ *
+ * Copyright 2009 The Geany contributors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/*
+ * A GtkLabel subclass that can wrap to any width, unlike GtkLabel which has a fixed wrap point.
+ * (inspired by libview's WrapLabel, https://view.sourceforge.net/)
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "prjorg-wraplabel.h"
+
+
+struct _PrjorgWrapLabelClass
+{
+ GtkLabelClass parent_class;
+};
+
+typedef struct
+{
+ gint wrap_width;
+ gint wrap_height;
+} PrjorgWrapLabelPrivate;
+
+struct _PrjorgWrapLabel
+{
+ GtkLabel parent;
+ PrjorgWrapLabelPrivate *priv;
+};
+
+
+static gboolean prjorg_wrap_label_draw(GtkWidget *widget, cairo_t *cr);
+static void prjorg_wrap_label_get_preferred_width (GtkWidget *widget,
+ gint *minimal_width, gint *natural_width);
+static void prjorg_wrap_label_get_preferred_height (GtkWidget *widget,
+ gint *minimal_height, gint *natural_height);
+static void prjorg_wrap_label_get_preferred_width_for_height (GtkWidget *widget,
+ gint height, gint *minimal_width, gint *natural_width);
+static void prjorg_wrap_label_get_preferred_height_for_width (GtkWidget *widget,
+ gint width, gint *minimal_height, gint *natural_height);
+static GtkSizeRequestMode prjorg_wrap_label_get_request_mode(GtkWidget *widget);
+static void prjorg_wrap_label_size_allocate (GtkWidget *widget, GtkAllocation *alloc);
+static void prjorg_wrap_label_set_wrap_width (GtkWidget *widget, gint width);
+static void prjorg_wrap_label_label_notify (GObject *object, GParamSpec *pspec, gpointer data);
+
+G_DEFINE_TYPE(PrjorgWrapLabel, prjorg_wrap_label, GTK_TYPE_LABEL)
+
+
+static void prjorg_wrap_label_class_init(PrjorgWrapLabelClass *klass)
+{
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
+
+ widget_class->size_allocate = prjorg_wrap_label_size_allocate;
+ widget_class->draw = prjorg_wrap_label_draw;
+ widget_class->get_preferred_width = prjorg_wrap_label_get_preferred_width;
+ widget_class->get_preferred_width_for_height = prjorg_wrap_label_get_preferred_width_for_height;
+ widget_class->get_preferred_height = prjorg_wrap_label_get_preferred_height;
+ widget_class->get_preferred_height_for_width = prjorg_wrap_label_get_preferred_height_for_width;
+ widget_class->get_request_mode = prjorg_wrap_label_get_request_mode;
+
+ g_type_class_add_private(klass, sizeof (PrjorgWrapLabelPrivate));
+}
+
+
+static void prjorg_wrap_label_init(PrjorgWrapLabel *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE(self,
+ PRJORG_WRAP_LABEL_TYPE, PrjorgWrapLabelPrivate);
+
+ self->priv->wrap_width = 0;
+ self->priv->wrap_height = 0;
+
+ g_signal_connect(self, "notify::label", G_CALLBACK(prjorg_wrap_label_label_notify), NULL);
+ gtk_misc_set_alignment(GTK_MISC(self), 0.0, 0.0);
+}
+
+
+/* Sets the point at which the text should wrap. */
+static void prjorg_wrap_label_set_wrap_width(GtkWidget *widget, gint width)
+{
+ PrjorgWrapLabel *self = PRJORG_WRAP_LABEL(widget);
+ PangoLayout *layout;
+
+ if (width <= 0)
+ return;
+
+ layout = gtk_label_get_layout(GTK_LABEL(widget));
+
+ /*
+ * We may need to reset the wrap width, so do this regardless of whether
+ * or not we've changed the width.
+ */
+ pango_layout_set_width(layout, width * PANGO_SCALE);
+ pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
+ pango_layout_get_pixel_size(layout, NULL, &self->priv->wrap_height);
+
+ if (self->priv->wrap_width != width)
+ {
+ self->priv->wrap_width = width;
+ gtk_widget_queue_resize(widget);
+ }
+}
+
+
+/* updates the wrap width when the label text changes */
+static void prjorg_wrap_label_label_notify(GObject *object, GParamSpec *pspec, gpointer data)
+{
+ PrjorgWrapLabel *self = PRJORG_WRAP_LABEL(object);
+
+ prjorg_wrap_label_set_wrap_width(GTK_WIDGET(object), self->priv->wrap_width);
+}
+
+
+/* makes sure the layout is setup for rendering and chains to parent renderer */
+static gboolean prjorg_wrap_label_draw(GtkWidget *widget, cairo_t *cr)
+{
+ PrjorgWrapLabel *self = PRJORG_WRAP_LABEL(widget);
+ PangoLayout *layout = gtk_label_get_layout(GTK_LABEL(widget));
+
+ pango_layout_set_width(layout, self->priv->wrap_width * PANGO_SCALE);
+ pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
+
+ return (* GTK_WIDGET_CLASS(prjorg_wrap_label_parent_class)->draw)(widget, cr);
+}
+
+
+static void prjorg_wrap_label_get_preferred_width (GtkWidget *widget,
+ gint *minimal_width, gint *natural_width)
+{
+ *minimal_width = *natural_width = 0;
+}
+
+
+static void prjorg_wrap_label_get_preferred_width_for_height (GtkWidget *widget,
+ gint height, gint *minimal_width, gint *natural_width)
+{
+ PangoLayout *layout = gtk_label_get_layout(GTK_LABEL(widget));;
+
+ pango_layout_set_height(layout, height * PANGO_SCALE);
+ pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
+ pango_layout_get_pixel_size(layout, natural_width, NULL);
+
+ *minimal_width = 0;
+}
+
+
+static void prjorg_wrap_label_get_preferred_height (GtkWidget *widget,
+ gint *minimal_height, gint *natural_height)
+{
+ *minimal_height = *natural_height = PRJORG_WRAP_LABEL(widget)->priv->wrap_height;
+}
+
+
+static void prjorg_wrap_label_get_preferred_height_for_width (GtkWidget *widget,
+ gint width, gint *minimal_height, gint *natural_height)
+{
+ PangoLayout *layout = gtk_label_get_layout(GTK_LABEL(widget));
+
+ pango_layout_set_width(layout, width * PANGO_SCALE);
+ pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
+ pango_layout_get_pixel_size(layout, NULL, natural_height);
+
+ *minimal_height = *natural_height;
+}
+
+
+static GtkSizeRequestMode prjorg_wrap_label_get_request_mode(GtkWidget *widget)
+{
+ return GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT;
+}
+
+
+/* Sets the wrap width to the width allocated to us. */
+static void prjorg_wrap_label_size_allocate(GtkWidget *widget, GtkAllocation *alloc)
+{
+ GtkWidget *parent;
+
+ (* GTK_WIDGET_CLASS(prjorg_wrap_label_parent_class)->size_allocate)(widget, alloc);
+
+ prjorg_wrap_label_set_wrap_width(widget, alloc->width);
+
+ /* ask the parent to recompute our size, because it seems GTK size
+ * caching is too aggressive */
+ parent = gtk_widget_get_parent(widget);
+ if (GTK_IS_CONTAINER(parent))
+ gtk_container_check_resize(GTK_CONTAINER(parent));
+}
+
+
+GtkWidget *prjorg_wrap_label_new(const gchar *text)
+{
+ return g_object_new(PRJORG_WRAP_LABEL_TYPE, "label", text, NULL);
+}
Modified: projectorganizer/src/prjorg-wraplabel.h
49 lines changed, 49 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,49 @@
+/*
+ * prjorg- wraplabel.h - renamed copy of geanywraplabel.h from Geany
+ *
+ * Copyright 2009 The Geany contributors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef PRJORG_WRAP_LABEL_H
+#define PRJORG_WRAP_LABEL_H 1
+
+#include "gtkcompat.h"
+
+G_BEGIN_DECLS
+
+
+#define PRJORG_WRAP_LABEL_TYPE (prjorg_wrap_label_get_type())
+#define PRJORG_WRAP_LABEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \
+ PRJORG_WRAP_LABEL_TYPE, PrjorgWrapLabel))
+#define PRJORG_WRAP_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), \
+ PRJORG_WRAP_LABEL_TYPE, PrjorgWrapLabelClass))
+#define IS_PRJORG_WRAP_LABEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), \
+ PRJORG_WRAP_LABEL_TYPE))
+#define IS_PRJORG_WRAP_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), \
+ PRJORG_WRAP_LABEL_TYPE))
+
+
+typedef struct _PrjorgWrapLabel PrjorgWrapLabel;
+typedef struct _PrjorgWrapLabelClass PrjorgWrapLabelClass;
+
+GType prjorg_wrap_label_get_type (void);
+GtkWidget* prjorg_wrap_label_new (const gchar *text);
+
+
+G_END_DECLS
+
+#endif /* PRJORG_WRAP_LABEL_H */
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).