Merge trunk changes.

git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/branches/custom-filetypes@4142 ea778897-0a13-0410-b9d1-a72fbfd435f5
This commit is contained in:
Nick Treleaven 2009-08-31 15:46:19 +00:00
commit 89a708bd11
54 changed files with 4133 additions and 2779 deletions

25
HACKING
View File

@ -72,7 +72,7 @@ the existing elements stay in place - this will keep the ABI stable.
.. warning::
Some structs like GeanyKeyGroup and GeanyCallback cannot be
Some structs like GeanyKeyGroupInfo and GeanyCallback cannot be
appended to without breaking the ABI because they are used to declare
structs by plugins, not just for accessing struct members through
a pointer.
@ -82,7 +82,7 @@ even the API can change. An ABI change just means that all plugins will
not load and they must be rebuilt. An API change means that some plugins
might not build correctly.
When reordering or changing existing elements of structs that are
If you're reordering or changing existing elements of structs that are
used as part of the plugin API, you should increment GEANY_ABI_VERSION
in plugindata.h. This is usually not needed if you're just appending
fields to structs. The GEANY_API_VERSION value should be incremented
@ -90,6 +90,15 @@ for any changes to the plugin API, including appending elements.
If you're in any doubt when making changes to plugin API code, just ask us.
Plugin API/ABI design
---------------------
You should not make plugins rely on the size of a struct. This means:
* Don't let plugins allocate any structs (stack or heap).
* Don't let plugins index any arrays of structs.
* Don't add any array fields to structs in case we want to change the
array size later.
Glade
-----
Use the code generation features of Glade instead of editing interface.c
@ -192,17 +201,7 @@ check to see if those features have been written in other projects first.
* Add GEANY_FILETYPES_FOO to filetypes.h.
* Initialize GEANY_FILETYPES_FOO in init_builtin_filetypes() of
filetypes.c.
* Rebuild Geany.
* From your geany/ directory, run::
src/geany --generate-data-files
(The src/ prefix may be different, depending on where the binary is
generated.)
This will update data/filetype_extensions.conf. Note that
you need GEANY_DEBUG to be defined when building Geany for the
--generate-data-files argument to work - this is always defined in the
SVN version. Alternatively, edit the file by hand.
* Update data/filetype_extensions.conf.
filetypes.* configuration file
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

97
NEWS
View File

@ -1,3 +1,96 @@
Geany 0.18 (August 16, 2009)
General:
* Fix scrolling horizontally after finding a search match with the
search bar or Find Next/Previous which is off-screen.
* Remove relative/untidy path elements from filenames when opening
documents (#2823998).
* Create initial template files with proper platform-specific line
ending characters.
* Improve inserting of comment templates like File header or licence
notices.
Interface:
* Add 'Show Paths' documents list popup item.
* Add filetypes.common to 'Configuration Files' menu.
* Implement a graphical toolbar editor.
* Add 'Build' toolbar button to the default layout.
* Add 'Replace' toolbar button (closes #2798225).
* Use a more Tango like icon for 'Save All' (by Jesse Mayes, thanks).
* Add a popup menu for the keybinding list in the preferences dialog
to easily expand and collapse all groups.
Keybindings:
* Implement Most-Recently-Used document switching when pressing
'Switch to last used document' keybinding (Ctrl-Tab).
* Add 'Mark All' keybinding (Ctrl-Shift-M).
* Add 'Reflow lines/block' keybinding, (Ctrl-J; thanks to
Eugene Arshinov).
* Make the Scintilla keybindings 'Delete to end of line' and
'Go to end of display line' configurable.
* Switching notebook tabs now works for the currently used notebook
widget instead of always using the documents notebook.
Editor:
* Fix a redraw when documents were first drawn uncolourised.
* Delay highlighting matching braces by 100ms to speed up scrolling
with the arrow keys.
* Support 'tab indents, space aligns' style when indenting (#2789109).
* Add 'Autocomplete all words in document' pref; also used when forcing
autocompletion and there's no symbol names to show.
* Add 'Drop rest of word on completion' pref.
* Update Scintilla to version 1.79.
* Improve displaying and reshowing of calltips.
Syntax highlighting:
* Reload color schemes via Tools menu (thanks to Eugene Arshinov).
* Implement named styles support for filetypes.* using a
filetypes.common [named_styles] section; used as
"style=named_style,bold". (See the manual for details).
* Allow style definitions with missing fields to use the
filetypes.common default style's fields.
* Make C-like filetype styles use named styles & default background
color. (Anyone who wants to likewise update any other filetype's
styles, please let us know ;-)).
* Allow indentation of wrapped lines (see style 'line_wrap_indent').
* Add new styles 'line_height' and 'marker_mark'.
Filetypes:
* Add Markdown filetype (thanks to Jon Strait).
* Highlight D WYSIWYG backtick `strings` and r"strings" (#1895745).
* Minor improvements for filetypes: Fortran, Haxe, HTML, Lua,
Matlab, Pascal, Python, Tcl.
Tags:
* Read custom system global tags files from $prefix/share/geany/tags
(#2778923).
* Autocomplete scoped fields like struct members when typing '.' (and
also '->' or '::' in C/C++) if the language's tag parser supports it.
* Save field tags for C/C++ when generating a global tags file (you may
want to regenerate your tag files).
* Parse Python calltips.
* Show relative paths in Diff filename tags.
* Group reStructuredText symbol list items by scope level.
Plugin API:
* Add geanyplugin.h single include.
* Add plugin_signal_connect() for connecting plugin signals at
runtime and also for connecting to any GObject signal.
* Add documents_foreach(), filetypes[], documents[], utils_strdupa()
and various foreach_type() macros.
* Make GeanyDocument::file_type always be non-NULL.
Windows:
* Fix quoting the build command string on Windows (closes #2791769).
* Fix LaTeX view commands on Windows (part of #2807688).
* Expand system environment variables (%variableName%) on Windows when
running Build commands.
Internationalisation:
* Added translations: lb, sl, pt_PT
* Updated translations: ca, cs, de, en_GB, fi, fr, ja, pt_BR, ru, tr
Geany 0.17 (May 02, 2009)
Bug fixes:
@ -299,7 +392,7 @@ Geany 0.14 (April 19, 2008)
* Add translucency settings to filetypes.common for semi-transparency.
* Add HTML parser to get h1, h2, h3 symbols as well as link anchors and
JavaScript functions (fixes #1896068).
* Update Javascript, TCL and Assembler parser.
* Update Javascript, Tcl and Assembler parser.
Interface:
* When closing a tab when using left-to-right tabs, focus the next
@ -613,7 +706,7 @@ Geany 0.11 (May 21, 2007)
Tab.
* Add MimeType associatiations for: C++ header, Pascal, Perl,
Python, httpd-PHP and XML files (thanks to Iñaki Rodriguez).
* Add brace indenting support for Perl and TCL.
* Add brace indenting support for Perl and Tcl.
* Make backspace unindent when using spaces for indentation.
* Wrap notebook pages when switching tabs.
* Speed up loading multiple C-like files slightly.

View File

@ -2,7 +2,7 @@ dnl Process this file with autoconf to produce a configure script.
dnl $Id$
AC_INIT(configure.in)
AM_INIT_AUTOMAKE(geany, 0.18)
AM_INIT_AUTOMAKE(geany, 0.19)
AM_CONFIG_HEADER(config.h)

View File

@ -1,5 +1,3 @@
#*** This file generated by: geany --generate-data-files ***
# Filetype extension configuration file for Geany
# Insert as many items as you want, seperate them with a ";".
# See Geany's main documentation for details.
@ -7,7 +5,7 @@
ASM=*.asm;
Ada=*.adb;*.ads;
C=*.c;*.h;
C++=*.cpp;*.cxx;*.c++;*.cc;*.h;*.hpp;*.hxx;*.h++;*.hh;*.C;
C++=*.cpp;*.cxx;*.c++;*.cc;*.h;*.hpp;*.hxx;*.h++;*.hh;*.C;*.H;
C#=*.cs;
CAML=*.ml;*.mli;
D=*.d;*.di;

View File

@ -43,3 +43,17 @@ compiler=latex --file-line-error-style "%f"
linker=pdflatex --file-line-error-style "%f"
run_cmd=xdvi "%f"
run_cmd2=xpdf "%f"
[build-menu]
FT_00_LB=LaTeX -> _DVI
FT_00_CM=latex --file-line-error-style "%f"
FT_00_BD=false
FT_01_LB=LaTeX -> _PDF
FT_01_CM=pdflatex --file-line-error-style "%f"
FT_01_BD=false
EX_00_LB=V_iew PDF File
EX_00_CM=xpdf "%f"
EX_00_BD=false
EX_01_LB=_View DVI File
EX_01_CM=xdvi "%f"
EX_01_BD=false

26
data/filetypes.markdown Normal file
View File

@ -0,0 +1,26 @@
# For complete documentation of this file, please see Geany's main documentation
[styling]
# foreground;background;bold;italic
# default=0x000000;0xffffff;false;false
# strong=0xff0000;0xffffff;false;false
# emphasis=0xff0000;0xffffff;false;false
# header1=0x0000bb;0xffffff;false;false
# header2=0x0000bb;0xffffff;false;false
# header3=0x0000bb;0xffffff;false;false
# header4=0x0000bb;0xffffff;false;false
# header5=0x0000bb;0xffffff;false;false
# header6=0x0000bb;0xffffff;false;false
# ulist_item=0x007f00;0xffffff;false;false
# olist_item=0x007f00;0xffffff;false;false
# blockquote=0xff0000;0xffffff;false;false
# strikeout=0xaa00ff;0xffffff;false;false
# hrule=0xff901e;0xffffff;false;false
# link=0x0000ff;0xffffff;false;false
# code=0x009f00;0xffffff;false;false
# codebk=0x005f00;0xffffff;false;false
[settings]
# default extension used when saving files
extension=mdml

View File

@ -94,7 +94,8 @@ WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = ../src/ ./ ../plugins/pluginmacros.h ../plugins/geanyplugin.h \
INPUT = ../src/ ./ \
../plugins/pluginmacros.h ../plugins/geanyplugin.h ../plugins/geanyfunctions.h \
../tagmanager/tm_source_file.c ../tagmanager/include/tm_source_file.h \
../tagmanager/tm_work_object.c ../tagmanager/include/tm_work_object.h \
../tagmanager/tm_workspace.c ../tagmanager/include/tm_workspace.h
@ -228,7 +229,7 @@ SEARCH_INCLUDES = NO
INCLUDE_PATH =
INCLUDE_FILE_PATTERNS =
# make G_GNUC_PRINTF a no-op unless doxygen would ignore functions with varargs
PREDEFINED = "G_GNUC_PRINTF(x,y)=" GEANY_DISABLE_DEPRECATED HAVE_PLUGINS
PREDEFINED = "G_GNUC_PRINTF(x,y)=" GEANY_DISABLE_DEPRECATED HAVE_PLUGINS GEANY_FUNCTIONS_H
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = NO
#---------------------------------------------------------------------------

View File

@ -1,4 +1,4 @@
.TH "GEANY" "1" "May 02, 2009" "geany @VERSION@" ""
.TH "GEANY" "1" "August 16, 2009" "geany @VERSION@" ""
.SH "NAME"
Geany \(em a small and lightweight IDE
.SH "SYNOPSIS"

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
.. |(version)| replace:: 0.18
.. |(version)| replace:: 0.19
=======
Geany
@ -44,7 +44,7 @@ Some basic features of Geany:
* Syntax highlighting
* Code folding
* Symbol name autocompletion
* Autocompletion of symbols/words
* Construct completion/snippets
* Auto-closing of XML and HTML tags
* Calltips
@ -865,6 +865,24 @@ word on completion* preference is set (in `Editor Completions tab in
preferences dialog`_) then any characters after the cursor that match
a symbol or word are deleted.
Scope autocompletion
````````````````````
E.g.::
struct
{
int i;
char c;
} foo;
When you type ``foo.`` it will show an autocompletion list with 'i' and
'c' symbols.
It only works for languages that set parent scope names for e.g. struct
members. Currently this means C-like languages. The C tag parser only
parses global scopes, so this won't work for structs or objects declared
in local scope.
User-definable snippets
^^^^^^^^^^^^^^^^^^^^^^^
@ -1588,10 +1606,6 @@ Show documents list
change between documents (see `Switching between documents`_) and
to perform some common operations such as saving, closing and reloading.
Show full path name in documents list
Show the full directory path of the files you are editing in the
*Documents* list.
Fonts
`````
@ -1996,9 +2010,6 @@ Tools tab in preferences dialog
Tool paths
``````````
Make
The location of the make executable.
Terminal
The location of your terminal executable.
@ -2158,7 +2169,8 @@ Follow path of the current file
Execute programs in VTE
Execute programs in the virtual terminal instead of using the external
terminal tool.
terminal tool. Note that if you run multiple execute commands at once
the output may become mixed together in the VTE.
Don't use run script
Don't use the simple run script which is usually used to display
@ -2173,22 +2185,21 @@ Project Management
Project Management is optional in Geany. Currently it can be used for:
* Storing and opening session files on a project basis.
* Running *Make* from the project's base directory.
* Setting a custom *Run* command specific to the project.
* Configuring the Build menu on a project basis.
A list of session files can be stored and opened with the project
when the *Use project-based session files* preference is enabled,
in the *Project* group of the `Preferences`_ dialog.
As long as a project is open, the Make and Run commands will use
the project's settings, instead of the defaults. These will be used
whichever document is currently displayed.
As long as a project is open, the Build menu will use
the items defined in project's settings, instead of the defaults.
See `Build Menu Configuration` for information on configuring the menu.
The current project's settings are saved when it is closed, or when
Geany is shutdown. When restarting Geany, the previously opened project
file that was in use at the end of the last session will be reopened.
Below are the commands used to create, modify, open and close projects.
The project menu items are detailed below.
New Project
@ -2210,34 +2221,20 @@ Project Properties
You can set an optional description for the project, but it is not
used elsewhere by Geany.
The *Base path* field is used as the directory to run the Make and Make
custom commands in. It is also used as working directory for the project
specific *Run command*.
The specified path can be an absolute path or relative to the project's
file name.
The *Base path* field is used as the directory to run the Build menu commands.
The specified path can be an absolute path or it is considered to be
relative to the project's file name.
Make in base path
`````````````````
Set Base Path Button
````````````````````
This setting makes the *Build->Make* command use the project's base
path. Uncheck this if you want to use the current file's directory
instead.
This button is a convenience to set the working directory fields
in the non-filetype Build menu items to %p to use the project base path.
Run command
```````````
The *Run command* overrides the default run command. You can set this
to the executable or main script file for the project, and append
any command-line arguments.
The following variables can be used:
* %f -- complete filename without path
* %e -- filename without path and without extension
See `[build_settings] Section`_ for details.
.. note::
Pressing the 'set' button will overright any working directories
you have configured for the project.
Open Project
@ -2260,27 +2257,48 @@ When project session support is enabled, Geany will close the project
session files and open any previously closed default session files.
Build system
------------
Build Menu
----------
After editing code with Geany, the next step is to compile, link, build,
interpret, run etc. As Geany supports many languages each with a different
approach to such operations, and as there are also many language independant
software building systems, Geany does not have a built in build system, nor
does it limit which system you can use. Instead the build menu provides
a configurable and flexible means of running any external commands.
Geany has an integrated build system. Firstly this means that the
current source file will be saved before it is processed. This is
for convenience so that you don't need to keep saving small changes
to the current file before building.
This section provides a description of the default configuration of the
build menu and then covers how to configure it, and where the defaults fit in.
Secondly the output for Compile, Build and Make actions will be captured
in the Compiler notebook tab of the messages window. If there are
any warnings or errors with line numbers shown in red in the Compiler
output tab, you can click on them and Geany will switch to the relevant
source file (or open it) and mark the line number so the problem can be
corrected. Geany will also set indicators for warnings or errors with
line numbers.
Running the commands from within Geany has two benefits:
* the current file is automatically saved before the command is run
* the output is captured in the Compiler notebook tab and parsed for
warnings or errors
Warnings and errors that can be parsed for line numbers will be shown in
red in the Compiler tab and you can click on them to switch to the relevant
source file (or open it) and mark the line number. Also lines with
warnings or errors are marked in the source, see `Indicators`_ below.
.. tip::
If Geany's default error message parsing does not parse errors for
the tool you're using, you can set a custom regex. See `Filetype
definition files`_ and the `[build_settings] Section`_.
the tool you're using, you can set a custom regex in the Build Commands
Dialog, see `Build Menu Configuration`
Indicators
^^^^^^^^^^
Indicators are red squiggly underlines which are used to highlight
errors which occurred while compiling the current file. So you can
easily see where your code failed to compile. To remove the indicators,
just select "Remove all indicators" in the document file menu.
If you do not like this feature, you can disable it in the preferences
dialog.
Default Build Menu Items
^^^^^^^^^^^^^^^^^^^^^^^^
Depending on the current file's filetype, the Build menu will contain
the following items:
@ -2289,26 +2307,29 @@ the following items:
* Make All
* Make Custom Target
* Make Object
* Next Error
* Previous Error
* Execute
* Set Includes and Arguments
* Set Build Menu Commands
Compile
^^^^^^^
```````
The Compile command has different uses for different kinds of files.
For compilable languages such as C and C++, the Compile command is
setup to compile the current source file into a binary object file.
Java source files will be compiled to class file bytecode. Interpreted
languages such as Perl, Python, Ruby will compile to bytecode if the
language supports it, or will run a syntax check, or failing that
will run the file in its language interpreter.
Java source files will be compiled to class file bytecode.
Interpreted languages such as Perl, Python, Ruby will compile to
bytecode if the language supports it, or will run a syntax check,
or if that is not available will run the file in its language interpreter.
Build
^^^^^
`````
For compilable languages such as C and C++, the Build command will link
the current source file's equivalent object file into an executable. If
@ -2318,62 +2339,70 @@ in one step, producing just the executable binary.
Interpreted languages do not use the Build command.
Make all
^^^^^^^^
Make
````
This effectively runs "make all" in the same directory as the
This runs "make" in the same directory as the
current file.
.. note::
For each of the Make commands, The Make tool path must be correctly
set in the Tools tab of the Preferences dialog.
Make custom target
^^^^^^^^^^^^^^^^^^
``````````````````
This is similar to running 'Make all' but you will be prompted for
This is similar to running 'Make' but you will be prompted for
the make target name to be passed to the Make tool. For example,
typing 'clean' in the dialog prompt will run "make clean".
Make object
^^^^^^^^^^^
```````````
Make object will run "make current_file.o" in the same directory as
the current file, using its prefix for 'current_file'. It is useful
for compiling just the current file without building the whole project.
the current file, using the filename for 'current_file'. It is useful
for building just the current file without building the whole project.
Next Error
``````````
The next error item will move to the next detected error in the file.
Previous Error
``````````````
The previous error item will move to the previous detected error in the file.
Execute
^^^^^^^
```````
Execute will run the corresponding executable file, shell script or
interpreted script in a terminal window. Note that the Terminal tool
path must be correctly set in the Tools tab of the Preferences dialog -
you can use any terminal program that runs a Bourne compatible shell
and accept the "-e" command line argument to start a command.
and accept the "-e" command line argument to start a command or can be
selected to us the build-in VTE if it is available, see
`Virtual terminal emulator widget (VTE)`_.
After your program or script has finished executing, you will be
prompted to press the return key. This allows you to review any text
output from the program before the terminal window is closed.
The execute command output is not parsed for errors.
Stopping running processes
^^^^^^^^^^^^^^^^^^^^^^^^^^
``````````````````````````
When there is a running program, the Run button in the toolbar
becomes a stop button and you can stop the current action. This
When there is a running program, the Execute menu item in the menu and
the Run button in the toolbar
becomes a stop button and you can stop the current running program. This
works by sending a signal to the process (and its child process(es))
to stop the process. The used signal is SIGQUIT.
to stop the process. The signal used is SIGQUIT.
Depending on the process you started it might occur that the process
cannot be stopped. This can happen when the process creates more than
one child process.
Depending on the process you started it is possible that the process
cannot be stopped. For example this can happen when the process creates
more than one child process.
Terminal emulators
``````````````````
******************
Xterm is known to work properly. If you are using "Terminal"
(the terminal program of Xfce), you should add the command line
@ -2382,15 +2411,17 @@ stopped. Just add this option in the preferences dialog on the Tools
tab in the terminal field.
Set Includes and Arguments
^^^^^^^^^^^^^^^^^^^^^^^^^^
Set Build Commands
``````````````````
By default the Compile and Build commands invoke the compiler and
By default the Compile and Build commands invoke the GCC compiler and
linker with only the basic arguments needed by all programs. Using
Set Includes and Arguments you can add any include paths and compile
Set Build Commands you can add any include paths and compile
flags for the compiler, any library names and paths for the linker,
and any arguments you want to use when running Execute.
For details of configuration see `Build Menu Configuration`_ below.
.. note::
If you need complex settings for your build system, or several
different settings, then writing a Makefile and using the Make
@ -2399,35 +2430,195 @@ and any arguments you want to use when running Execute.
These settings are saved automatically when Geany is shut down.
The following variables can be used:
Build Menu Configuration
^^^^^^^^^^^^^^^^^^^^^^^^
* %f -- complete filename without path
* %e -- filename without path and without extension
The build menu has considerable flexibility and configurability, allowing
both menu labels the commands they execute and the directory they execute
in to be configured.
See `[build_settings] Section`_ for details.
For example, if you change one of the default make commands to run say 'waf'
you can also change the label to match.
Underlines in the labels set mnemonic characters.
The build menu is divided into four groups of items each with different
behaviors:
One step compilation
````````````````````
* file items - are configurable and depend on the filetype of the current
document, put the output in the compiler tab and parse it for errors
* non-file items - are configurable and mostly don't depend on the filetype
of the current document, put the output in the compiler tab and parse
it for errors
* execute items - are configurable and intended for executing your
program or other long running programs. The output is not parsed for errors
and is directed to the terminal selected in preferences.
* fixed items - are not configurable because they perform the Geany built in actions,
go to the next error, go to the previous error and show the build menu
commands dialog
If you are using the Build command to compile and link in one step,
you will need to set both the compiler arguments and the linker
arguments in the linker command setting.
The maximum numbers of items in each of the configurable groups can be
configured when Geany starts using hidden settings(see `Preferences File Format`).
Even though the maximum number of items may have been increased, only
those menu items that have values configured are shown in the menu.
The groups of menu items obtain their configuration from four potential
sources. The highest pririty source that has the menu item defined will
be used. The sources in decreasing priority are:
Indicators
^^^^^^^^^^
* a project file if open
* the user preferences
* the system filetype definitions
* the defaults
Indicators are red squiggly underlines which are used to highlight
errors which occurred while compiling the current file. So you can
easily see where your code failed to compile. To remove the indicators,
just click on "Remove all indicators" in the document file menu.
The detailed relationships between sources and the configurable menu item groups
is shown in the following table.
If you do not like this feature, you can disable it in the preferences
dialog.
+--------------+---------------------+--------------------------+-------------------+-------------------------------+
| Group | Project File | Preferences | System Filetype | Defaults |
+==============+=====================+==========================+===================+===============================+
| Filetype | Loads From: project | Loads From: | Loads From: | None |
| | file | filetype.xxx file in | filetype.xxx in | |
| | | ~/.config/geany/filedefs | Geany install | |
| | Saves To: project | | | |
| | file | Saves to: as above, | Saves to: as user | |
| | | creating if needed. | preferences left. | |
+--------------+---------------------+--------------------------+-------------------+-------------------------------+
| Non-Filetype | Loads From: project | Loads From: | Loads From: | 1: |
| | file | geany.conf file in | filetype.xxx in | Label: _Make |
| | | ~/.config/geany | Geany install | Command: make |
| | Saves To: project | | | |
| | file | Saves to: as above, | Saves to: as user | 2: |
| | | creating if needed. | preferences left. | Label: Make Custom _Target |
| | | | | Command: make |
| | | | | |
| | | | | 3: |
| | | | | Label: Make _Object |
| | | | | Command: make %e.o |
+--------------+---------------------+--------------------------+-------------------+-------------------------------+
| Execute | Loads From: project | Loads From: | Loads From: | Label: _Execute Command: ./%e |
| | file or else | geany.conf file in | filetype.xxx in | |
| | filetype defined in | ~/.config/geany or else | Geany install | |
| | project file | filetype.xxx file in | | |
| | | ~/.config/geany/filedefs | Saves To: as user | |
| | Saves To: | | preferences left | |
| | project file | Saves To: | | |
| | | geany.conf file in | | |
| | | ~/.config/geany | | |
+--------------+---------------------+--------------------------+-------------------+-------------------------------+
The following notes on the table reference cells by coordinate as (group,source):
* General - for filetype.xxx substitute the appropriate extension for the
current document for xxx.
* System Filetypes - Labels loaded from these sources are locale sensitive
and can contain translations.
* (Filetype, Project File) and (Filetype, Preferences) - preferences use a full
filetype file so that users can configure all other filetype preferences
as well. Projects can only configure menu items per filetype. Saving
in the project file means that there is only one file per project not
a whole directory.
* (Non-Filetype, System Filetype) - although conceptually strange, defining
non-filetype commands in a filetype file, this provides the ability to
define filetype dependent default menu items.
* (Execute, Project File) and (Execute, Preferences) - the filetype based execute
configuration can only be set by hand editing the appropriate file, see
`Preferences File Format` and `Project File Format`.
Build Menu Commands Dialog
^^^^^^^^^^^^^^^^^^^^^^^^^^
Most of the configuration of the build menu is done through the Build Menu
Commands Dialog. You edit the configuration sourced from preferences in the
dialog opened from the Build->Build Menu Commands item and you edit the
configuration from the project in the build tab of the project preferences
dialog. Both use the same form shown below.
.. image:: ./images/build_menu_commands_dialog.png
The dialog is divided into three sections:
* Filetype menu items which will be selected based on the filetype of the
currently open document,
* Non-filetype menu items, and
* Execute menu items.
The filetype and non-filetype sections also contain a field for the regular
expression used for parsing command output for error and warning messages.
The columns in the first three sections allow setting of the label, command,
and working directory to run the command in.
An item with an empty label will not be shown in the menu.
An empty working directory will default to the directory of the current document.
If there is no current document then the command will not run.
The dialog will always show the command selected by priority, not just the
commands configured in this configuration source. This ensures that you always
see what the menu item is going to do if activated.
If the current source of the menu item is higher priority than the
configuration source you are editing then the command will be shown
in the dialog but will be insensitive (greyed out). This can't happen
with the project source but can with the preferences source dialog.
The clear buttons remove the definition from the configuration source you are editing.
When you do this the command from the next lower priority source will be shown.
To hide lower priority menu items without having anything show in the menu
configure with a nothing in the label but at least one character in the command.
Substitutions in Commands and Working Directories
`````````````````````````````````````````````````
The first occurance of each of the following character sequences in each of the
command and working directory fields is substituted by the items specified below
before the command is run.
* %d - substituted by the absolute path to the directory of the current file.
* %e - substituted by the name of the current file without the extension or path.
* %f - substituted by the name of the current file without the path.
* %p - if a project is open, substituted by the base path from the project.
.. note::
If the basepath set in the project preferences is not an absolute path , then it is
taken as relative to the directory of the project file. This allows a project file
stored in the source tree to specify all commands and working directories relative
to the tree itself, so that the whole tree including the project file, can be moved
and even checked into and out of version control without having to re-configure the
build menu.
Build Menu Keyboard Shortcuts
`````````````````````````````
Keyboard shortcuts can be defiend for the first two filetype menu items, the first three
non-filetype menu items, the first two execute menu items and the fixed menu items.
In the keybindings configuration dialog (see `Keybinding tab in preferences dialog`_)
these items are identified by the default labels shown in the `Build Menu`_ section above.
It is currently not possible to bind keyboard shortcuts to more than these menu items.
Configuration Files
```````````````````
The configurable Build Menu capability was introduced in Geany V0.19 and
required a new section to be added to the configuration files (See
`Preferences File Format`_). Geany will still load older format project,
preferences and filetype file settings and will attempt to map them into the new
configuration format. There is not a simple clean mapping between the formats.
The mapping used produces the most sensible results for the majority of cases.
However, if they do not map the way you want, you may have to manually
configure some settings using the Build Commands
Dialog or the Build tab of the project preferences dialog.
Any setting configured in either of these dialogs will override settings mapped from
older format configuration files.
Printing support
----------------
@ -2710,7 +2901,8 @@ Send Selection to Terminal Sends the current sele
line (if there is no selection) to the
embedded Terminal (VTE).
Reflow lines/paragraph Reformat selected lines or current paragraph,
Reflow lines/block Reformat selected lines or current
(indented) text block,
breaking lines at the long line marker.
@ -2746,6 +2938,11 @@ Find Document Usage Finds all occurrences
document and displays them in the messages
window.
Mark All Highlight all matches of the current
word/selection in the current document
with a colored box. If there's nothing to
find, highlighted matches will be cleared.
**Go to**
Navigate forward a location Switches to the next location in the navigation
@ -2916,6 +3113,27 @@ Configuration files
===================
Tools menu items
----------------
There's a *Configuration files* submenu in the *Tools* menu that
contains items for some of the available user configuration files.
Clicking on one opens it in the editor for you to update. Geany will
reload the file after you have saved it.
.. note::
Other configuration files are not shown here and you will need to open
them manually and usually restart Geany to see any changes.
There's also a *Reload Configuration* item which can be used if you
updated a configuration file outside of the current instance. This
item is also necessary to update syntax highlighting colors.
.. note::
Syntax highlighting colors aren't updated after saving
filetypes.common as this can take a short while depending on which
documents are open.
Global configuration file
-------------------------
@ -2974,6 +3192,8 @@ configuration directory. Alternatively, you can create a file
to change. All missing settings will be read from the corresponding
global definition file in ``$prefix/share/geany``.
As well as the sections listed below, each filetype file can contain
a [build-menu] section as described in `[build-menu] Section`_.
Format
^^^^^^
@ -3106,6 +3326,9 @@ context_action_cmd
[build_settings] Section
````````````````````````
As of Geany v0.19 this section is supplemented by the `[build-menu] Section`_.
error_regex
This is a GNU-style extended regular expression to parse a filename
and line number from build output. If undefined, Geany will fall
@ -3122,8 +3345,10 @@ error_regex
**Build commands**
The build commands are all configurable using the `Set Includes and
Arguments`_ dialog.
If any build menu item settings have been configured in the Build Menu Commands
dialog or the Build tab of the project preferences dialog then these
settings are stored in the [build-menu] section and override the settings in
this section for that item.
compiler
This item specifies the command to compile source code files. But
@ -3439,6 +3664,144 @@ look like::
[Extensions]
Make=Makefile*;*.mk;Buildfile;
Preferences File Format
-----------------------
The preferences file ``~/.config/geany/geany.conf`` holds settings for all the items configured
in the preferences dialog. These are not detailed as they should not be edited
as they are overwritten by Geany.
Hidden preferences
^^^^^^^^^^^^^^^^^^
There are some uncommon preferences that are not shown in the Preferences
dialog. These can be set by editing the preferences file, then
restarting Geany. Search for the key name, then edit the value. Example:
``brace_match_ltgt=true``
The table below show the key names of hidden preferences in the
configuration file.
================================ =========================================== ==================
Key Description Default
================================ =========================================== ==================
**Editor related**
brace_match_ltgt Whether to highlight <, > angle brackets. false
show_editor_scrollbars Whether to display scrollbars. If set to true
false, the horizontal and vertical
scrollbars are hidden completely.
use_gtk_word_boundaries Whether to look for the end of a word when true
using word-boundary related Scintilla
commands (see `Scintilla keyboard
commands`_).
complete_snippets_whilst_editing Whether to allow completion of snippets false
when editing an existing line (i.e. there
is some text after the current cursor
position on the line). Only used when the
keybinding ``Complete snippet`` is set to
``Space``.
**Interface related**
show_symbol_list_expanders Whether to show or hide the small expander true
icons on the symbol list treeview (only
available with GTK 2.12 or above).
allow_always_save Whether files can be saved always, even if false
they don't have any changes. By default,
the Save buttons and menu items are
disabled when a file is unchanged. When
setting this option to true, the Save
buttons and menu items are always active
and files can be saved.
**VTE related**
emulation Terminal emulation mode. Only change this xterm
if you have VTE termcap files other than
``vte/termcap/xterm``.
**File related**
use_safe_file_saving Defines the mode how Geany saves files to false
disk. If disabled, Geany directly writes
the content of the document to disk. This
might cause in loss of data when there is
no more free space on disk to save the
file. When set to true, Geany first saves
the contents into a temporary file and if
this succeeded, the temporary file is
moved to the real file to save.
This gives better error checking in case of
no more free disk space. But it also
destroys hard links of the original file
and its permissions (e.g. executable flags
are reset). Use this with care as it can
break things seriously.
The better approach would be to ensure your
disk won't run out of free space.
**Build Menu related**
number_ft_menu_items The maximum number of menu items in the 2
filetype section of the Build menu.
number_non_ft_menu_items The maximum number of menu items in the 3
non-filetype section of the Build menu.
number_exec_menu_items The maximum number of menu items in the 2
execute section of the Build menu.
================================ =========================================== ==================
[build-menu] Section
^^^^^^^^^^^^^^^^^^^^
The [build-menu] section contains the configuration of the build menu.
This section can occur in filetype, preferences and project files and
always has the format described here. Different menu items are loaded
from different files, see the table in the `Build Menu Configuration`
section for details. All the settings can be configured from the dialogs
except the execute command in filetype files and filetype definitions in
the project file, so these are the only ones which need hand editing.
The build-menu section stores one entry for each setting for each menu item that
is configured. The keys for these settings have the format:
``GG_NN_FF``
where:
* GG - is the menu item group,
- FT for filetype
- NF for non-filetype
- EX for execute
* NN - is a two decimal digit number of the item within the group,
starting at 00
* FF - is the field,
- LB for label
- CM for command
- WD for working directory
Project File Format
-------------------
The project file contains project related settings and possibly a
record of the current session files.
[build-menu] Additions
^^^^^^^^^^^^^^^^^^^^^^
The project file also can have extra fields in the [build-menu] section
in addition to those listed in `[build-menu] Section`_ above.
When filetype menu items are configured for the project they are stored
in the project file.
The ``filetypes`` entry is a list of the filetypes which exist in the
project file.
For each filetype the entries for that filetype have the format defined in
`[build-menu] Section` but the key is prefixed by the name of the filetype
as it appears in the ``filetypes`` entry, eg the entry for the label of
filetype menu item 0 for the C filetype would be
``CFT_00_LB=Label``
Templates
@ -3836,71 +4199,6 @@ them on Windows):
position without having to drag it.
Hidden preferences
==================
There are some uncommon preferences that are not shown in the Preferences
dialog. These can be set by editing ``~/.config/geany/geany.conf``, then
restarting Geany. Search for the key name, then edit the value. Example:
``brace_match_ltgt=true``
The table below show the key names of hidden preferences in the
configuration file.
================================ =========================================== ==================
Key Description Default
================================ =========================================== ==================
**Editor related**
brace_match_ltgt Whether to highlight <, > angle brackets. false
show_editor_scrollbars Whether to display scrollbars. If set to true
false, the horizontal and vertical
scrollbars are hidden completely.
use_gtk_word_boundaries Whether to look for the end of a word when true
using word-boundary related Scintilla
commands (see `Scintilla keyboard
commands`_).
complete_snippets_whilst_editing Whether to allow completion of snippets false
when editing an existing line (i.e. there
is some text after the current cursor
position on the line). Only used when the
keybinding ``Complete snippet`` is set to
``Space``.
**Interface related**
show_symbol_list_expanders Whether to show or hide the small expander true
icons on the symbol list treeview (only
available with GTK 2.12 or above).
allow_always_save Whether files can be saved always, even if false
they don't have any changes. By default,
the Save buttons and menu items are
disabled when a file is unchanged. When
setting this option to true, the Save
buttons and menu items are always active
and files can be saved.
**VTE related**
emulation Terminal emulation mode. Only change this xterm
if you have VTE termcap files other than
``vte/termcap/xterm``.
**File related**
use_safe_file_saving Defines the mode how Geany saves files to false
disk. If disabled, Geany directly writes
the content of the document to disk. This
might cause in loss of data when there is
no more free space on disk to save the
file. When set to true, Geany first saves
the contents into a temporary file and if
this succeeded, the temporary file is
moved to the real file to save.
This gives better error checking in case of
no more free disk space. But it also
destroys hard links of the original file
and its permissions (e.g. executable flags
are reset). Use this with care as it can
break things seriously.
The better approach would be to ensure your
disk won't run out of free space.
================================ =========================================== ==================
Compile-time options
====================
@ -4014,6 +4312,23 @@ GEANY_BUILD_ERR_HIGHLIGHT_MAX Amount of build error messages which should 10
just aftereffects.
============================== ============================================ ==================
build.c
-------
============================== ============================================ ==================
Option Description Default
============================== ============================================ ==================
PRINTBUILDCMDS Every time a build menu item priority FALSE
calculation is run, print the state of the
menu item table in the form of the table
in `Build Menu Configuration`_. May be
useful to debug configuration file
overloading. Warning produces a lot of
output. Can also be enabled/disabled by the
debugger by setting printbuildcmds to 1/0
overriding the compile setting.
============================== ============================================ ==================
GNU General Public License

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -35,8 +35,7 @@
* @date $Date$
*
* @section Intro
* This is the Geany API documentation. It is far from being complete and should be
* considered as a work in progress.
* This is the Geany API documentation. It should be considered work in progress.
* We will try to document as many functions and structs as possible.
*
* To get started, see the @link howto Plugin Howto @endlink.
@ -47,8 +46,13 @@
* - @link signals Plugin Signals @endlink
* - @link pluginutils.c Plugin Utility Functions @endlink
* - @link guidelines Plugin Writing Guidelines @endlink
* - <b>plugins/demoplugin.c</b> - in Geany's source, bigger than the howto example
* - Header files for functions and types - see <b>Files</b> link at the top
* - Deprecated symbols - see <b>Related Pages</b> link at the top
*
* @note Some of these pages are also listed in Related Pages.
* @warning Do not use any symbol not in the documentation - it may change.
* @note See the HACKING file for information about developing the plugin API and
* other useful notes.
*/
/**

View File

@ -70,16 +70,10 @@ PluginFields *plugin_fields;
* @see plugin_signal_connect(). */
PluginCallback plugin_callbacks[];
/** Most plugins should use the PLUGIN_KEY_GROUP() macro to define it. However,
* its fields are not read until after plugin_init() is called for the plugin, so it
* is possible to setup a variable number of keybindings, e.g. based on the
* plugin's configuration file settings.
* - The @c name field must not be empty or match Geany's default group name.
* - The @c label field is set by Geany after plugin_init() is called to the name of the
* plugin.
* @note This is a single element array for implementation reasons,
* but you can treat it like a pointer. */
KeyBindingGroup plugin_key_group[1];
/** Plugins must use the PLUGIN_KEY_GROUP() macro to define it.
* To setup a variable number of keybindings, e.g. based on the
* plugin's configuration file settings, use plugin_set_key_group() instead. */
KeyBindingGroup *plugin_key_group;
/** Called before showing the plugin preferences dialog to let the user set some basic

View File

@ -7706,34 +7706,6 @@ Match braces</property>
<property name="row_spacing">3</property>
<property name="column_spacing">6</property>
<child>
<widget class="GtkLabel" id="label11">
<property name="visible">True</property>
<property name="label" translatable="yes">Make:</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label97">
<property name="visible">True</property>
@ -7790,28 +7762,6 @@ Match braces</property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="entry_com_make">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Path and options for the make tool</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char">*</property>
<property name="activates_default">False</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="entry_com_term">
<property name="visible">True</property>
@ -7856,35 +7806,6 @@ Match braces</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="button_make">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<child>
<widget class="GtkImage" id="image285">
<property name="visible">True</property>
<property name="stock">gtk-open</property>
<property name="icon_size">4</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
</child>
</widget>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkButton" id="button_term">
<property name="visible">True</property>

View File

@ -33,8 +33,8 @@ RequestExecutionLevel user ; set execution level for Windows Vista
; helper defines ;
;;;;;;;;;;;;;;;;;;;
!define PRODUCT_NAME "Geany"
!define PRODUCT_VERSION "0.18"
!define PRODUCT_VERSION_ID "0.18.0.0"
!define PRODUCT_VERSION "0.19"
!define PRODUCT_VERSION_ID "0.19.0.0"
!define PRODUCT_PUBLISHER "The Geany developer team"
!define PRODUCT_WEB_SITE "http://www.geany.org/"
!define PRODUCT_DIR_REGKEY "Software\Geany"
@ -54,7 +54,7 @@ VIAddVersionKey "ProductVersion" "${PRODUCT_VERSION}"
VIAddVersionKey "LegalCopyright" "Copyright 2005-2009 by the Geany developer team"
VIAddVersionKey "FileDescription" "${PRODUCT_NAME} Installer"
BrandingText "$(^NAME) installer (NSIS 2.44)"
BrandingText "$(^NAME) installer (NSIS 2.45)"
InstallDir "$PROGRAMFILES\Geany"
Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"
SetCompressor /SOLID lzma

View File

@ -5,8 +5,8 @@
A ICON MOVEABLE PURE LOADONCALL DISCARDABLE "../icons/geany.ico"
1 VERSIONINFO
FILEVERSION 0,18,0,0
PRODUCTVERSION 0,18,0,0
FILEVERSION 0,19,0,0
PRODUCTVERSION 0,19,0,0
FILETYPE VFT_APP
{
BLOCK "StringFileInfo"
@ -14,14 +14,14 @@ FILETYPE VFT_APP
BLOCK "040704E4"
{
VALUE "CompanyName", ""
VALUE "FileVersion", "0.18"
VALUE "FileVersion", "0.19"
VALUE "FileDescription", "Geany"
VALUE "InternalName", "geany"
VALUE "LegalCopyright", "Copyright 2005-2009 by the Geany developers"
VALUE "LegalTrademarks", ""
VALUE "OriginalFilename", "geany"
VALUE "ProductName", "geany"
VALUE "ProductVersion", "0.18"
VALUE "ProductVersion", "0.19"
}
}
}

View File

@ -1,10 +1,16 @@
/* This file is generated automatically by genapi.py - do not edit.
/* This file is generated automatically by genapi.py - do not edit. */
/** @file geanyfunctions.h @ref geany_functions wrappers.
* This allows the use of normal API function names in plugins by defining macros.
*
* E.g.:@code
* #define plugin_add_toolbar_item \
* geany_functions->p_plugin->add_toolbar_item @endcode
*
* @file geanyfunctions.h @ref geany_functions wrappers.
* This allows the use of normal API function names in plugins.
* You need to declare the @ref geany_functions symbol yourself.
*
* Note: This must be included after all other API headers.
* Note: This must be included after all other API headers to prevent conflicts with
* other header's function prototypes - this is done for you when using geanyplugin.h.
*/
#ifndef GEANY_FUNCTIONS_H
@ -16,6 +22,8 @@
geany_functions->p_plugin->module_make_resident
#define plugin_signal_connect \
geany_functions->p_plugin->signal_connect
#define plugin_set_key_group \
geany_functions->p_plugin->set_key_group
#define document_new_file \
geany_functions->p_document->new_file
#define document_get_current \
@ -246,6 +254,8 @@
geany_functions->p_keybindings->send_command
#define keybindings_set_item \
geany_functions->p_keybindings->set_item
#define keybindings_get_item \
geany_functions->p_keybindings->get_item
#define tm_get_real_path \
geany_functions->p_tm->get_real_path
#define tm_source_file_new \

View File

@ -26,7 +26,7 @@ r"""
Creates macros for each plugin API function pointer, e.g.:
#define plugin_add_toolbar_item \
p_plugin->add_toolbar_item
geany_functions->p_plugin->add_toolbar_item
"""
@ -56,13 +56,19 @@ def get_api_tuple(str):
header = \
'''/* This file is generated automatically by genapi.py - do not edit.
r'''/* This file is generated automatically by genapi.py - do not edit. */
/** @file %s @ref geany_functions wrappers.
* This allows the use of normal API function names in plugins by defining macros.
*
* E.g.:@code
* #define plugin_add_toolbar_item \
* geany_functions->p_plugin->add_toolbar_item @endcode
*
* @file %s @ref geany_functions wrappers.
* This allows the use of normal API function names in plugins.
* You need to declare the @ref geany_functions symbol yourself.
*
* Note: This must be included after all other API headers.
* Note: This must be included after all other API headers to prevent conflicts with
* other header's function prototypes - this is done for you when using geanyplugin.h.
*/
#ifndef GEANY_FUNCTIONS_H

View File

@ -39,6 +39,7 @@ PLUGIN_SET_INFO(_("Split Window"), _("Splits the editor view into two windows.")
GeanyData *geany_data;
GeanyFunctions *geany_functions;
GeanyPlugin *geany_plugin;
/* Keybinding(s) */
@ -50,9 +51,6 @@ enum
KB_COUNT
};
PLUGIN_KEY_GROUP(split_window, KB_COUNT);
enum State
{
STATE_SPLIT_HORIZONTAL,
@ -97,11 +95,10 @@ static gint sci_get_value(ScintillaObject *sci, gint message_id, gint param)
static void set_styles(ScintillaObject *oldsci, ScintillaObject *newsci)
{
gint style_id;
gint val;
for (style_id = 0; style_id <= 127; style_id++)
{
gint val;
val = sci_get_value(oldsci, SCI_STYLEGETFORE, style_id);
scintilla_send_message(newsci, SCI_STYLESETFORE, style_id, val);
val = sci_get_value(oldsci, SCI_STYLEGETBACK, style_id);
@ -111,6 +108,8 @@ static void set_styles(ScintillaObject *oldsci, ScintillaObject *newsci)
val = sci_get_value(oldsci, SCI_STYLEGETITALIC, style_id);
scintilla_send_message(newsci, SCI_STYLESETITALIC, style_id, val);
}
val = sci_get_value(oldsci, SCI_GETCARETFORE, 0);
scintilla_send_message(newsci, SCI_SETCARETFORE, val, 0);
}
@ -395,6 +394,7 @@ static void kb_activate(guint key_id)
void plugin_init(GeanyData *data)
{
GtkWidget *item, *menu;
GeanyKeyGroup *key_group;
menu_items.main = item = gtk_menu_item_new_with_mnemonic(_("_Split Window"));
gtk_menu_shell_append(GTK_MENU_SHELL(geany_data->main_widgets->tools_menu), item);
@ -423,11 +423,12 @@ void plugin_init(GeanyData *data)
set_state(STATE_UNSPLIT);
/* setup keybindings */
keybindings_set_item(plugin_key_group, KB_SPLIT_HORIZONTAL, kb_activate,
key_group = plugin_set_key_group(geany_plugin, "split_window", KB_COUNT, NULL);
keybindings_set_item(key_group, KB_SPLIT_HORIZONTAL, kb_activate,
0, 0, "split_horizontal", _("Split Horizontally"), menu_items.horizontal);
keybindings_set_item(plugin_key_group, KB_SPLIT_VERTICAL, kb_activate,
keybindings_set_item(key_group, KB_SPLIT_VERTICAL, kb_activate,
0, 0, "split_vertical", _("Split Vertically"), menu_items.vertical);
keybindings_set_item(plugin_key_group, KB_SPLIT_UNSPLIT, kb_activate,
keybindings_set_item(key_group, KB_SPLIT_UNSPLIT, kb_activate,
0, 0, "split_unsplit", _("Unsplit"), menu_items.unsplit);
}

View File

@ -1,5 +1,5 @@
#!/usr/bin/env perl
# Copyright: 2008, Nick Treleaven
# Copyright: 2008-2009, Nick Treleaven
# License: GNU GPL V2 or later
# Warranty: NONE
@ -8,6 +8,18 @@
# repeats until all matching blocks of text are found.
# Results are printed in reverse, hence in chronological order (as ChangeLogs
# are usually written in reverse date order).
#
# The resulting lines are then formatted to be easier to read and edit into a
# NEWS file.
# Example ChangeLog format:
#2009-04-03 Joe Author <joe@example.net>
#
# * src/file.c, src/file.h,
# src/another.c:
# Some change description,
# spanning several lines.
# * foo.c: Combined line.
use strict;
use warnings;
@ -15,8 +27,12 @@ use warnings;
my $scriptname = "changelist.pl";
my $argc = $#ARGV + 1;
($argc == 2)
or die "Usage:\n$scriptname matchstring changelogfile\n";
($argc == 2) or die <<END;
Usage:
$scriptname matchstring changelogfile >outfile
matchstring is not case sensitive.
END
my ($matchstr, $infile) = @ARGV;
@ -24,7 +40,10 @@ open(INPUT, $infile)
or die "Couldn't open $infile for reading: $!\n";
my $entry; # the current matching block of text
my @entries;
my @entries; # changelog entries, one per date
# first parse each ChangeLog entry into an array
my $found = 0; # if we're in a matching block of text
my $blank = 0; # whether the last line was empty
@ -34,8 +53,7 @@ while (<INPUT>) {
if (! $found) {
($line =~ m/$matchstr/) and $found = 1;
} else {
if (length($line) <= 1) # current line is empty
{
if (length($line) <= 1) { # current line is empty
if ($blank > 0) { # previous line was also empty
push(@entries, $entry); # append entry
$entry = "";
@ -47,10 +65,61 @@ while (<INPUT>) {
}
}
}
$found and $entry .= $line;
if ($found) {
$entry .= $line;
}
}
close(INPUT);
# reformat entries
foreach $entry (reverse @entries) {
print "$entry\n\n";
my @lines = split(/\n/, $entry);
my $fl = 0; # in file list lines
my $cm = 0; # in commit message lines
foreach my $line (@lines){
my $flset = $fl;
# strip trailing space
$line =~ s/\s+$//g;
if (!$cm){
# check if in filelist
($line =~ m/ \* /) and $fl = 1;
# join filelist together on one line
$fl and ($line =~ s/^ / /);
if ($fl and ($line =~ m/:/)){
$fl = 0;
# separate ' * foo.c: Some edit.' messages:
if (!($line =~ m/:$/)) {
($line =~ s/:/:\n*/);
}
}
$fl and ($line =~ m/,$/) or $fl = 0;
}
if (!$flset){
# Asterisk commit messages
if (!$cm and ($line =~ m/^ /)){
$cm = 1;
$line =~ s/^( )/$1* /;
} else {
$cm and ($line =~ s/^( )/$1 /); # indent continuing lines
}
$cm and ($line =~ m/\.$/) and $cm = 0;
}
#~ print $fl.','.$cm.','.$line."\n"; next; # debug
# change file list start char to easily distinguish between file list and commit messages
$line =~ s/^ \* /@ /g;
# strip <email> from date line
$line =~ s/^([0-9-]+.*?)\s+<.+>$/$1/g;
# remove indent
$line =~ s/^ //g;
if ($line ne ""){
print $line;
(!$fl) and print "\n";
}
}
print "\n";
}

View File

@ -73,10 +73,12 @@ geany_include_HEADERS = \
templates.h \
toolbar.h \
ui_utils.h \
utils.h
utils.h \
build.h
INCLUDES = -I$(srcdir)/../scintilla/include -I$(srcdir)/../tagmanager/include @GTK_CFLAGS@ @GIO_CFLAGS@
INCLUDES = -I$(top_srcdir) -I$(srcdir)/../scintilla/include -I$(srcdir)/../tagmanager/include \
@GTK_CFLAGS@ @GIO_CFLAGS@
# tell automake we have a C++ file so it uses the C++ linker we need for Scintilla
nodist_EXTRA_geany_SOURCES = dummy.cxx
@ -94,7 +96,8 @@ AM_CFLAGS = -DGEANY_DATADIR=\"data\" \
-DGEANY_DOCDIR=\"\" \
-DGEANY_LIBDIR=\"\" \
-DGEANY_LOCALEDIR=\"\" \
-DGEANY_PREFIX=\"\"
-DGEANY_PREFIX=\"\" \
-DGEANY_PRIVATE
geany_LDFLAGS = -mwindows -mms-bitfields
@ -117,7 +120,8 @@ AM_CFLAGS = -DGEANY_DATADIR=\""$(datadir)"\" \
-DGEANY_DOCDIR=\""$(docdir)"\" \
-DGEANY_LIBDIR=\""$(libdir)"\" \
-DGEANY_LOCALEDIR=\""$(localedir)"\" \
-DGEANY_PREFIX=\""$(prefix)"\"
-DGEANY_PREFIX=\""$(prefix)"\" \
-DGEANY_PRIVATE
clean-local:

File diff suppressed because it is too large Load Diff

View File

@ -21,24 +21,96 @@
* $Id$
*/
/* * @file build.h Interface to the Build menu functionality. */
#ifndef GEANY_BUILD_H
#define GEANY_BUILD_H 1
#define GEANY_BUILD_ERR_HIGHLIGHT_MAX 100
typedef enum /* Geany Build Options */
/* Order is important (see GBO_TO_GBG, GBO_TO_CMD below) */
/** Geany Known Build Commands.
* These commands are named after their default use.
* Only these commands can currently have keybindings.
**/
typedef enum
{
GBO_COMPILE,
GBO_BUILD,
GBO_MAKE_ALL,
GBO_MAKE_CUSTOM,
GBO_MAKE_OBJECT
GEANY_GBO_COMPILE, /**< default compile file */
GEANY_GBO_BUILD, /**< default build file */
GEANY_GBO_MAKE_ALL, /**< default make */
GEANY_GBO_CUSTOM, /**< default make user specified target */
GEANY_GBO_MAKE_OBJECT, /**< default make object, make %e.o */
GEANY_GBO_EXEC, /**< default execute ./%e */
GEANY_GBO_COUNT /**< count of how many */
} GeanyBuildType;
/** Groups of Build menu items. */
typedef enum
{
GEANY_GBG_FT, /**< filetype items */
GEANY_GBG_NON_FT, /**< non filetype items.*/
GEANY_GBG_EXEC, /**< execute items */
GEANY_GBG_COUNT /**< count of groups. */
} GeanyBuildGroup;
/* include the fixed widgets in an array indexed by groups */
#define GBG_FIXED GEANY_GBG_COUNT
/** Convert @c GeanyBuildType to @c GeanyBuildGroup.
*
* This macro converts @c GeanyBuildType enum values (the "known" commands)
* to the group they are part of.
*
* @param gbo the @c GeanyBuildType value.
*
* @return the @c GeanyBuildGroup group that @a gbo is in.
*
* Note this is a macro so that it can be used in static initialisers.
**/
#define GBO_TO_GBG(gbo) ((gbo)>GEANY_GBO_EXEC?GEANY_GBG_COUNT:((gbo)>=GEANY_GBO_EXEC?GEANY_GBG_EXEC: \
((gbo)>=GEANY_GBO_MAKE_ALL?GEANY_GBG_NON_FT:GEANY_GBG_FT)))
/** Convert @c GeanyBuildType to command index.
*
* This macro converts @c GeanyBuildType enum values (the "known" commands)
* to the index within the group.
*
* @param gbo the @c GeanyBuildType value.
*
* @return the index of the @a gbo command in its group.
*
* Note this is a macro so that it can be used in static initialisers.
**/
#define GBO_TO_CMD(gbo) ((gbo)>=GEANY_GBO_COUNT?(gbo)-GEANY_GBO_COUNT:((gbo)>=GEANY_GBO_EXEC?(gbo)-GEANY_GBO_EXEC: \
((gbo)>=GEANY_GBO_MAKE_ALL?(gbo)-GEANY_GBO_MAKE_ALL:(gbo))))
enum GeanyBuildFixedMenuItems
{
GBF_NEXT_ERROR,
GBF_PREV_ERROR,
GBF_COMMANDS,
GBF_SEP_1,
GBF_SEP_2,
GBF_SEP_3,
GBF_SEP_4,
GBF_COUNT
};
/** Build menu item sources in increasing priority */
typedef enum
{
GEANY_BCS_DEF, /**< Default values. */
GEANY_BCS_FT, /**< System filetype values. */
GEANY_BCS_HOME_FT, /**< Filetypes in ~/.config/geany/filedefs */
GEANY_BCS_PREF, /**< Preferences file ~/.config/geany/geany.conf */
GEANY_BCS_PROJ, /**< Project file if open. */
GEANY_BCS_COUNT /**< Count of sources. */
} GeanyBuildSource;
typedef struct GeanyBuildInfo
{
GeanyBuildType type; /* current action(one of the above enumeration) */
GeanyBuildGroup grp;
gint cmd;
GPid pid; /* process id of the spawned process */
gchar *dir;
guint file_type_id;
@ -48,37 +120,150 @@ typedef struct GeanyBuildInfo
extern GeanyBuildInfo build_info;
/** The entries of a command for a menu item */
typedef enum GeanyBuildCmdEntries
{
GEANY_BC_LABEL, /**< The menu item label, _ marks mnemonic */
GEANY_BC_COMMAND, /**< The command to run. */
GEANY_BC_WORKING_DIR, /**< The directory to run in */
GEANY_BC_CMDENTRIES_COUNT, /**< Count of entries */
} GeanyBuildCmdEntries;
/** The command for a menu item. */
typedef struct GeanyBuildCommand
{
/** Pointers to g_string values of the command entries.
* Must be freed if the pointer is changed. */
gchar *entries[GEANY_BC_CMDENTRIES_COUNT];
gboolean exists; /**< If the entries have valid values. */
gboolean changed; /**< Save on exit if @c changed, remove if not @c exist. */
gboolean old; /**< Converted from old format. */
} GeanyBuildCommand;
extern GeanyBuildCommand *non_ft_proj, *exec_proj; /* project command array pointers */
extern gchar *regex_proj; /* project non-fileregex string */
typedef struct BuildMenuItems
{
GtkWidget *menu;
GtkWidget *item_compile;
GtkWidget *item_link;
GtkWidget *item_make_all;
GtkWidget *item_make_custom;
GtkWidget *item_make_object;
GtkWidget *item_next_error;
GtkWidget *item_previous_error;
GtkWidget *item_exec;
GtkWidget *item_exec2;
GtkWidget *item_set_args;
GtkWidget **menu_item[GEANY_GBG_COUNT+1]; /* +1 for fixed items */
} BuildMenuItems;
/* a structure defining the destinations for a set of groups of commands & regex */
typedef struct BuildDestination
{
GeanyBuildCommand **dst[GEANY_GBG_COUNT];
gchar **fileregexstr;
gchar **nonfileregexstr;
} BuildDestination;
/* opaque pointers returned from build functions and passed back to them */
typedef struct TableFields *TableData;
void build_init(void);
void build_finalize(void);
/* menu configuration dialog functions */
GtkWidget *build_commands_table( GeanyDocument *doc, GeanyBuildSource dst, TableData *data, GeanyFiletype *ft );
gboolean build_read_commands( BuildDestination *dst, TableData data, gint response );
void build_free_fields( TableData data );
void build_set_non_ft_wd_to_proj(TableData table_data);
/* build response decode assistance function */
gboolean build_parse_make_dir(const gchar *string, gchar **prefix);
/* build menu functions */
/** Update the build menu to reflect changes in configuration or status.
*
* Sets the labels and number of visible items to match the highest
* priority configured commands. Also sets sensitivity if build commands are
* running and switches executes to stop when commands are running.
*
* @param doc The current document, if available, to save looking it up.
* If @c NULL it will be looked up.
*
* Call this after modifying any fields of a GeanyBuildCommand structure.
*
* @see Build Menu Configuration section of the Manual.
*
**/
void build_menu_update(GeanyDocument *doc);
BuildMenuItems *build_get_menu_items(gint filetype_idx);
void build_toolbutton_build_clicked(GtkAction *action, gpointer user_data);
/** Remove the specified Build menu item.
*
* Makes the specified menu item configuration no longer exist. This
* is different to setting fields to blank because the menu item
* will be deleted from the configuration file on saving
* (except the system filetypes settings @see Build Menu Configuration
* section of the Manual).
*
* @param src the source of the menu item to remove.
* @param grp the group of the command to remove.
* @param cmd the index (from 0) of the command within the group. A negative
* value will remove the whole group.
*
* If any parameter is out of range does nothing.
*
* @see build_menu_update
**/
void build_remove_menu_item(GeanyBuildSource src, GeanyBuildGroup grp, gint cmd);
/** Get the @a GeanyBuildCommand structure for the specified Build menu item.
*
* Get the command for any menu item specified by @a src, @a grp and @a cmd even if it is
* hidden by higher priority commands.
*
* @param src the source of the specified menu item.
* @param grp the group of the specified menu item.
* @param cmd the index of the command within the group.
*
* @return a pointer to the @a GeanyBuildCommand structure or @a NULL if it doesn't exist.
* This is a pointer to an internal structure and must not be freed.
*
* @see build_menu_update
**/
GeanyBuildCommand *build_get_menu_item(GeanyBuildSource src, GeanyBuildGroup grp, gint cmd);
/** Get the @a GeanyBuildCommand structure for the menu item.
*
* Get the current highest priority command specified by @a grp and @a cmd. This is the one
* that the menu item will use if activated.
*
* @param grp the group of the specified menu item.
* @param cmd the index of the command within the group.
* @param src pointer to @a gint to return which source provided the command. Ignored if @a NULL.
* Values are one of @a GeanyBuildSource but returns a signed type not the enum.
*
* @return a pointer to the @a GeanyBuildCommand structure or @a NULL if it doesn't exist.
* This is a pointer to an internal structure and must not be freed.
*
* @see build_menu_update
**/
GeanyBuildCommand *build_get_current_menu_item(GeanyBuildGroup grp, gint cmd, gint *src);
BuildMenuItems *build_get_menu_items(gint filetype_idx);
/* load and store menu configuration */
void build_load_menu( GKeyFile *config, GeanyBuildSource dst, gpointer ptr);
void build_save_menu( GKeyFile *config, gpointer ptr, GeanyBuildSource src);
void build_set_group_count(GeanyBuildGroup grp, gint count);
gint build_get_group_count(GeanyBuildGroup grp);
gchar **build_get_regex(GeanyBuildGroup grp, GeanyFiletype *ft, gint *from);
#endif

View File

@ -1466,11 +1466,18 @@ on_insert_date_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
GeanyDocument *doc = document_get_current();
gchar *format;
gchar *format = NULL;
gchar *time_str;
g_return_if_fail(doc != NULL);
/* set default value */
if (utils_str_equal("", ui_prefs.custom_date_format))
{
g_free(ui_prefs.custom_date_format);
ui_prefs.custom_date_format = g_strdup("%d.%m.%Y");
}
if (utils_str_equal(_("dd.mm.yyyy"), (gchar*) user_data))
format = "%d.%m.%Y";
else if (utils_str_equal(_("mm.dd.yyyy"), (gchar*) user_data))
@ -1487,13 +1494,6 @@ on_insert_date_activate (GtkMenuItem *menuitem,
format = ui_prefs.custom_date_format;
else
{
/* set default value */
if (utils_str_equal("", ui_prefs.custom_date_format))
{
g_free(ui_prefs.custom_date_format);
ui_prefs.custom_date_format = g_strdup("%d.%m.%Y");
}
dialogs_show_input(_("Custom Date Format"),
_("Enter here a custom date and time format. You can use any conversion specifiers which can be used with the ANSI C strftime function."),
ui_prefs.custom_date_format, FALSE, &on_custom_date_input_response);
@ -1866,7 +1866,7 @@ on_menu_open_selected_file1_activate (GtkMenuItem *menuitem,
if (sel != NULL)
{
gchar *locale_filename, *filename;
gchar *locale_filename, *filename = NULL;
if (g_path_is_absolute(sel))
filename = g_strdup(sel);
@ -1874,7 +1874,10 @@ on_menu_open_selected_file1_activate (GtkMenuItem *menuitem,
{ /* relative filename, add the path of the current file */
gchar *path;
path = g_path_get_dirname(doc->file_name);
path = utils_get_current_file_dir_utf8();
if (!path)
path = g_get_current_dir();
filename = g_build_path(G_DIR_SEPARATOR_S, path, sel, NULL);
if (! g_file_test(filename, G_FILE_TEST_EXISTS) &&

View File

@ -1308,6 +1308,9 @@ GeanyDocument *document_open_file_full(GeanyDocument *doc, const gchar *filename
if (reload)
ui_set_statusbar(TRUE, _("File %s reloaded."), display_filename);
else
/* For translators: this is the status window message for opening a file. %d is the number
* of the newly opened file, %s indicates whether the file is opened read-only
* (it is replaced with the string ", read-only"). */
msgwin_status_add(_("File %s opened(%d%s)."),
display_filename, gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets.notebook)),
(readonly) ? _(", read-only") : "");

View File

@ -657,8 +657,12 @@ static void on_char_added(GeanyEditor *editor, SCNotification *nt)
case ':': /* C/C++ class:: syntax */
/* tag autocompletion */
default:
#if 0
if (! editor_start_auto_complete(editor, pos, FALSE))
request_reshowing_calltip(nt);
#else
editor_start_auto_complete(editor, pos, FALSE);
#endif
}
check_line_breaking(editor, pos, nt->ch);
}

View File

@ -63,6 +63,7 @@ typedef struct GeanyFiletypePrivate
#ifdef HAVE_REGCOMP
regex_t error_regex;
gboolean error_regex_compiled;
gchar *last_string; /* last one compiled */
#endif
gboolean custom;
}
@ -624,8 +625,9 @@ static GeanyFiletype *filetype_new(void)
GeanyFiletype *ft = g_new0(GeanyFiletype, 1);
ft->lang = -2; /* assume no tagmanager parser */
ft->programs = g_new0(struct build_programs, 1);
ft->actions = g_new0(struct build_actions, 1);
/* ft->programs = g_new0(struct build_programs, 1);
ft->actions = g_new0(struct build_actions, 1);*/
ft->project_list_entry = -1; /* no entry */
ft->priv = g_new0(GeanyFiletypePrivate, 1);
return ft;
@ -1142,12 +1144,9 @@ static void filetype_free(gpointer data, G_GNUC_UNUSED gpointer user_data)
g_free(ft->comment_open);
g_free(ft->comment_close);
g_free(ft->context_action_cmd);
g_free(ft->programs->compiler);
g_free(ft->programs->linker);
g_free(ft->programs->run_cmd);
g_free(ft->programs->run_cmd2);
g_free(ft->programs);
g_free(ft->actions);
g_free(ft->filecmds);
g_free(ft->ftdefcmds);
g_free(ft->execcmds);
set_error_regex(ft, NULL);
g_strfreev(ft->pattern);
@ -1220,44 +1219,9 @@ static void load_settings(gint ft_id, GKeyFile *config, GKeyFile *configh)
}
/* read build settings */
result = g_key_file_get_string(configh, "build_settings", "compiler", NULL);
if (result == NULL) result = g_key_file_get_string(config, "build_settings", "compiler", NULL);
if (G_LIKELY(result != NULL))
{
filetypes[ft_id]->programs->compiler = result;
filetypes[ft_id]->actions->can_compile = TRUE;
}
build_load_menu( config, GEANY_BCS_FT, (gpointer)ft );
build_load_menu( configh, GEANY_BCS_HOME_FT, (gpointer)ft );
result = g_key_file_get_string(configh, "build_settings", "linker", NULL);
if (result == NULL) result = g_key_file_get_string(config, "build_settings", "linker", NULL);
if (result != NULL)
{
filetypes[ft_id]->programs->linker = result;
filetypes[ft_id]->actions->can_link = TRUE;
}
result = g_key_file_get_string(configh, "build_settings", "run_cmd", NULL);
if (result == NULL) result = g_key_file_get_string(config, "build_settings", "run_cmd", NULL);
if (G_LIKELY(result != NULL))
{
filetypes[ft_id]->programs->run_cmd = result;
filetypes[ft_id]->actions->can_exec = TRUE;
}
result = g_key_file_get_string(configh, "build_settings", "run_cmd2", NULL);
if (result == NULL) result = g_key_file_get_string(config, "build_settings", "run_cmd2", NULL);
if (result != NULL)
{
filetypes[ft_id]->programs->run_cmd2 = result;
filetypes[ft_id]->actions->can_exec = TRUE;
}
result = g_key_file_get_string(configh, "build_settings", "error_regex", NULL);
if (result == NULL) result = g_key_file_get_string(config, "build_settings", "error_regex", NULL);
if (result != NULL)
{
set_error_regex(ft, result);
}
}
@ -1356,29 +1320,15 @@ void filetypes_save_commands(void)
for (i = 1; i < filetypes_array->len; i++)
{
struct build_programs *bp = filetypes[i]->programs;
GKeyFile *config_home;
gchar *fname, *ext, *data;
if (! bp->modified)
continue;
ext = filetypes_get_conf_extension(i);
fname = g_strconcat(conf_prefix, ext, NULL);
g_free(ext);
config_home = g_key_file_new();
g_key_file_load_from_file(config_home, fname, G_KEY_FILE_KEEP_COMMENTS, NULL);
if (NZV(bp->compiler))
g_key_file_set_string(config_home, "build_settings", "compiler", bp->compiler);
if (NZV(bp->linker))
g_key_file_set_string(config_home, "build_settings", "linker", bp->linker);
if (NZV(bp->run_cmd))
g_key_file_set_string(config_home, "build_settings", "run_cmd", bp->run_cmd);
if (NZV(bp->run_cmd2))
g_key_file_set_string(config_home, "build_settings", "run_cmd2", bp->run_cmd2);
build_save_menu(config_home, (gpointer)(filetypes[i]), GEANY_BCS_HOME_FT);
data = g_key_file_to_data(config_home, NULL, NULL);
utils_write_file(fname, data);
g_free(data);
@ -1469,9 +1419,9 @@ static gchar *get_regex_match_string(const gchar *message, regmatch_t *pmatch, g
}
static void compile_regex(GeanyFiletype *ft, regex_t *regex)
static void compile_regex(GeanyFiletype *ft, regex_t *regex, gchar *regstr)
{
gint retval = regcomp(regex, ft->error_regex_string, REG_EXTENDED);
gint retval = regcomp(regex, regstr, REG_EXTENDED);
ft->priv->error_regex_compiled = (retval == 0); /* prevent recompilation */
@ -1490,22 +1440,41 @@ static void compile_regex(GeanyFiletype *ft, regex_t *regex)
gboolean filetypes_parse_error_message(GeanyFiletype *ft, const gchar *message,
gchar **filename, gint *line)
{
gchar *regstr;
gchar **tmp;
GeanyDocument *doc;
#ifdef HAVE_REGCOMP
regex_t *regex;
regmatch_t pmatch[3];
#endif
if (ft == NULL)
{
doc = document_get_current();
if (doc != NULL)
ft = doc->file_type;
}
tmp = build_get_regex(build_info.grp, ft, NULL);
if (tmp == NULL)
return FALSE;
regstr = *tmp;
#ifndef HAVE_REGCOMP
if (!NZV(ft->error_regex_string))
if (!NZV(regstr))
geany_debug("No regex support - maybe you should configure with --enable-gnu-regex!");
return FALSE;
#else
regex_t *regex = &ft->priv->error_regex;
regmatch_t pmatch[3];
regex = &ft->priv->error_regex;
*filename = NULL;
*line = -1;
if (!NZV(ft->error_regex_string))
if (!NZV(regstr))
return FALSE;
if (!ft->priv->error_regex_compiled)
compile_regex(ft, regex);
if (!ft->priv->error_regex_compiled || regstr!=ft->priv->last_string)
{
compile_regex(ft, regex, regstr);
ft->priv->last_string=regstr;
}
if (!ft->priv->error_regex_compiled) /* regex error */
return FALSE;

View File

@ -27,11 +27,12 @@
#include "Scintilla.h"
#include "ScintillaWidget.h"
#include "build.h"
typedef enum
{
GEANY_FILETYPES_NONE = 0, /* first filetype is always None */
GEANY_FILETYPES_NONE = 0, /* first filetype is always None & must be 0 */
GEANY_FILETYPES_PHP,
GEANY_FILETYPES_BASIC, /* FreeBasic */
@ -99,23 +100,6 @@ GeanyFiletypeGroupID;
#define FILETYPE_ID(filetype_ptr) \
(((filetype_ptr) != NULL) ? (filetype_ptr)->id : GEANY_FILETYPES_NONE)
struct build_actions
{
gboolean can_compile;
gboolean can_link;
gboolean can_exec;
};
struct build_programs
{
gchar *compiler;
gchar *linker;
gchar *run_cmd;
gchar *run_cmd2;
gboolean modified;
};
/** Represents a filetype. */
struct GeanyFiletype
{
@ -131,12 +115,22 @@ struct GeanyFiletype
gchar *comment_open;
gchar *comment_close;
gboolean comment_use_indent;
struct build_programs *programs;
struct build_actions *actions; /* TODO: make private */
GeanyFiletypeGroupID group;
gchar *error_regex_string;
struct GeanyFiletypePrivate *priv; /* must be last, append fields before this item */
#ifdef GEANY_PRIVATE
/* Do not use following fields in plugins */
GeanyBuildCommand *filecmds; /* these need to be visible since used in build.c so not in private part */
GeanyBuildCommand *ftdefcmds; /* filetype dependent defaults for non_ft commands */
GeanyBuildCommand *execcmds;
GeanyBuildCommand *homefilecmds;
GeanyBuildCommand *homeexeccmds;
GeanyBuildCommand *projfilecmds;
gint project_list_entry;
gchar *projerror_regex_string;
gchar *homeerror_regex_string;
#endif
};
extern GPtrArray *filetypes_array;

View File

@ -47,7 +47,7 @@
* listed in the documentation should not be changed */
#define GEANY_FILEDEFS_SUBDIR "filedefs"
#define GEANY_TEMPLATES_SUBDIR "templates"
#define GEANY_CODENAME "Kaine"
#define GEANY_CODENAME "Vellam"
#define GEANY_HOMEPAGE "http://www.geany.org/"
#define GEANY_USE_WIN32_DIALOG 0
#define GEANY_STRING_UNTITLED _("untitled")
@ -91,4 +91,9 @@ extern gboolean ignore_callback;
/* prototype is here so that all files can use it. */
void geany_debug(gchar const *format, ...) G_GNUC_PRINTF (1, 2);
#ifndef G_GNUC_WARN_UNUSED_RESULT
#define G_GNUC_WARN_UNUSED_RESULT
#endif
#endif

View File

@ -2571,14 +2571,10 @@ create_prefs_dialog (void)
GtkWidget *vbox2;
GtkWidget *vbox33;
GtkWidget *table1;
GtkWidget *label11;
GtkWidget *label97;
GtkWidget *label117;
GtkWidget *entry_com_make;
GtkWidget *entry_com_term;
GtkWidget *entry_browser;
GtkWidget *button_make;
GtkWidget *image285;
GtkWidget *button_term;
GtkWidget *image286;
GtkWidget *button_browser;
@ -4161,13 +4157,6 @@ create_prefs_dialog (void)
gtk_table_set_row_spacings (GTK_TABLE (table1), 3);
gtk_table_set_col_spacings (GTK_TABLE (table1), 6);
label11 = gtk_label_new (_("Make:"));
gtk_widget_show (label11);
gtk_table_attach (GTK_TABLE (table1), label11, 0, 1, 0, 1,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
gtk_misc_set_alignment (GTK_MISC (label11), 0, 0.5);
label97 = gtk_label_new (_("Terminal:"));
gtk_widget_show (label97);
gtk_table_attach (GTK_TABLE (table1), label97, 0, 1, 1, 2,
@ -4182,13 +4171,6 @@ create_prefs_dialog (void)
(GtkAttachOptions) (0), 0, 0);
gtk_misc_set_alignment (GTK_MISC (label117), 0, 0.5);
entry_com_make = gtk_entry_new ();
gtk_widget_show (entry_com_make);
gtk_table_attach (GTK_TABLE (table1), entry_com_make, 1, 2, 0, 1,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
gtk_tooltips_set_tip (tooltips, entry_com_make, _("Path and options for the make tool"), NULL);
entry_com_term = gtk_entry_new ();
gtk_widget_show (entry_com_term);
gtk_table_attach (GTK_TABLE (table1), entry_com_term, 1, 2, 1, 2,
@ -4203,16 +4185,6 @@ create_prefs_dialog (void)
(GtkAttachOptions) (0), 0, 0);
gtk_tooltips_set_tip (tooltips, entry_browser, _("Path (and possibly additional arguments) to your favorite browser"), NULL);
button_make = gtk_button_new ();
gtk_widget_show (button_make);
gtk_table_attach (GTK_TABLE (table1), button_make, 2, 3, 0, 1,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
image285 = gtk_image_new_from_stock ("gtk-open", GTK_ICON_SIZE_BUTTON);
gtk_widget_show (image285);
gtk_container_add (GTK_CONTAINER (button_make), image285);
button_term = gtk_button_new ();
gtk_widget_show (button_term);
gtk_table_attach (GTK_TABLE (table1), button_term, 2, 3, 1, 2,
@ -4912,14 +4884,10 @@ create_prefs_dialog (void)
GLADE_HOOKUP_OBJECT (prefs_dialog, vbox2, "vbox2");
GLADE_HOOKUP_OBJECT (prefs_dialog, vbox33, "vbox33");
GLADE_HOOKUP_OBJECT (prefs_dialog, table1, "table1");
GLADE_HOOKUP_OBJECT (prefs_dialog, label11, "label11");
GLADE_HOOKUP_OBJECT (prefs_dialog, label97, "label97");
GLADE_HOOKUP_OBJECT (prefs_dialog, label117, "label117");
GLADE_HOOKUP_OBJECT (prefs_dialog, entry_com_make, "entry_com_make");
GLADE_HOOKUP_OBJECT (prefs_dialog, entry_com_term, "entry_com_term");
GLADE_HOOKUP_OBJECT (prefs_dialog, entry_browser, "entry_browser");
GLADE_HOOKUP_OBJECT (prefs_dialog, button_make, "button_make");
GLADE_HOOKUP_OBJECT (prefs_dialog, image285, "image285");
GLADE_HOOKUP_OBJECT (prefs_dialog, button_term, "button_term");
GLADE_HOOKUP_OBJECT (prefs_dialog, image286, "image286");
GLADE_HOOKUP_OBJECT (prefs_dialog, button_browser, "button_browser");

View File

@ -25,9 +25,12 @@
* Configurable keyboard shortcuts.
*/
#include <gdk/gdkkeysyms.h>
#include "geany.h"
#include <gdk/gdkkeysyms.h>
#include <string.h>
#include "keybindings.h"
#include "support.h"
#include "utils.h"
@ -107,37 +110,55 @@ static void cb_func_switch_tablastused(guint key_id);
static void cb_func_move_tab(guint key_id);
static void add_popup_menu_accels(void);
static void apply_kb_accel(GeanyKeyGroup *group, GeanyKeyBinding *kb, gpointer user_data);
/* This is used to set default keybindings on startup but at this point we don't want to
* assign the keybinding to the menu_item (apply_kb_accel) otherwise it can't be overridden
* by user keybindings anymore */
/** Lookup a keybinding item.
* @param group Group.
* @param key_id Keybinding index for the group.
* @return The keybinding.
* @since 0.19. */
GeanyKeyBinding *keybindings_get_item(GeanyKeyGroup *group, gsize key_id)
{
g_assert(key_id < group->count);
return &group->keys[key_id];
}
/* This is used to set default keybindings on startup.
* Menu accels are set in apply_kb_accel(). */
/** Simple convenience function to fill a GeanyKeyBinding struct item.
* @param group Group.
* @param key_id Keybinding index for the group.
* @param callback Function to call when activated.
* @param callback Function to call when activated, or @c NULL.
* @param key (Lower case) default key, e.g. @c GDK_j, but usually 0 for unset.
* @param mod Default modifier, e.g. @c GDK_CONTROL_MASK, but usually 0 for unset.
* @param name Not duplicated - use a static string.
* @param label Currently not duplicated - use a static or heap-allocated (e.g. translated) string.
* @param menu_item Optional widget to set an accelerator for, or @c NULL. */
void keybindings_set_item(GeanyKeyGroup *group, gsize key_id,
* @param kf_name Key name for the configuration file, such as @c "menu_new".
* @param label Label used in the preferences dialog keybindings tab.
* @param menu_item Optional widget to set an accelerator for, or @c NULL.
* @return The keybinding - normally this is ignored. */
GeanyKeyBinding *keybindings_set_item(GeanyKeyGroup *group, gsize key_id,
GeanyKeyCallback callback, guint key, GdkModifierType mod,
gchar *name, gchar *label, GtkWidget *menu_item)
gchar *kf_name, gchar *label, GtkWidget *menu_item)
{
GeanyKeyBinding *kb;
GeanyKeyBinding *kb = keybindings_get_item(group, key_id);
g_assert(key_id < group->count);
kb = &group->keys[key_id];
kb->name = name;
if (group->plugin)
{
/* some plugins e.g. GeanyLua need these fields duplicated */
setptr(kb->name, g_strdup(kf_name));
setptr(kb->label, g_strdup(label));
}
else
{
kb->name = kf_name;
kb->label = label;
}
kb->key = key;
kb->mods = mod;
kb->callback = callback;
kb->menu_item = menu_item;
return kb;
}
@ -488,8 +509,6 @@ static void init_default_kb(void)
0, 0, "build_previouserror", _("Previous error"), NULL);
keybindings_set_item(group, GEANY_KEYS_BUILD_RUN, cb_func_build_action,
GDK_F5, 0, "build_run", _("Run"), NULL);
keybindings_set_item(group, GEANY_KEYS_BUILD_RUN2, cb_func_build_action,
0, 0, "build_run2", _("Run (alternative command)"), NULL);
keybindings_set_item(group, GEANY_KEYS_BUILD_OPTIONS, cb_func_build_action,
0, 0, "build_options", _("Build options"), NULL);
@ -568,16 +587,6 @@ void keybindings_init(void)
}
static void apply_kb_accel(GeanyKeyGroup *group, GeanyKeyBinding *kb, gpointer user_data)
{
if (kb->key != 0 && kb->menu_item)
{
gtk_widget_add_accelerator(kb->menu_item, "activate", kb_accel_group,
kb->key, kb->mods, GTK_ACCEL_VISIBLE);
}
}
typedef void (*KBItemCallback) (GeanyKeyGroup *group, GeanyKeyBinding *kb, gpointer user_data);
static void keybindings_foreach(KBItemCallback cb, gpointer user_data)
@ -632,36 +641,42 @@ static void load_user_kb(void)
}
static void apply_kb_accel(GeanyKeyGroup *group, GeanyKeyBinding *kb, gpointer user_data)
{
if (kb->key != 0 && kb->menu_item)
{
gtk_widget_add_accelerator(kb->menu_item, "activate", kb_accel_group,
kb->key, kb->mods, GTK_ACCEL_VISIBLE);
}
}
void keybindings_load_keyfile(void)
{
load_user_kb();
add_popup_menu_accels();
/* set menu accels now, after user keybindings have been read and processed
* if we would set it before, user keybindings could not override menu item's default
* keybindings */
/* set menu accels now, after user keybindings have been read */
keybindings_foreach(apply_kb_accel, NULL);
}
static void add_menu_accel(GeanyKeyGroup *group, guint kb_id,
GtkAccelGroup *accel_group, GtkWidget *menuitem)
static void add_menu_accel(GeanyKeyGroup *group, guint kb_id, GtkWidget *menuitem)
{
GeanyKeyBinding *kb = &group->keys[kb_id];
if (kb->key != 0)
gtk_widget_add_accelerator(menuitem, "activate", accel_group,
gtk_widget_add_accelerator(menuitem, "activate", kb_accel_group,
kb->key, kb->mods, GTK_ACCEL_VISIBLE);
}
#define GEANY_ADD_POPUP_ACCEL(kb_id, wid) \
add_menu_accel(group, kb_id, accel_group, ui_lookup_widget(main_widgets.editor_menu, G_STRINGIFY(wid)))
add_menu_accel(group, kb_id, ui_lookup_widget(main_widgets.editor_menu, G_STRINGIFY(wid)))
/* set the menu item accelerator shortcuts (just for visibility, they are handled anyway) */
static void add_popup_menu_accels(void)
{
GtkAccelGroup *accel_group = gtk_accel_group_new();
GeanyKeyGroup *group;
group = g_ptr_array_index(keybinding_groups, GEANY_KEY_GROUP_EDITOR);
@ -698,8 +713,6 @@ static void add_popup_menu_accels(void)
GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_FORMAT_SENDTOVTE, send_selection_to_vte2);
/* the build menu items are set if the build menus are created */
gtk_window_add_accel_group(GTK_WINDOW(main_widgets.window), accel_group);
}
@ -1077,6 +1090,37 @@ static gboolean check_vte(GdkModifierType state, guint keyval)
#endif
/* Map the keypad keys to their equivalent functions (taken from ScintillaGTK.cxx) */
static guint key_kp_translate(guint key_in)
{
switch (key_in)
{
case GDK_KP_Down:
return GDK_Down;
case GDK_KP_Up:
return GDK_Up;
case GDK_KP_Left:
return GDK_Left;
case GDK_KP_Right:
return GDK_Right;
case GDK_KP_Home:
return GDK_Home;
case GDK_KP_End:
return GDK_End;
case GDK_KP_Page_Up:
return GDK_Page_Up;
case GDK_KP_Page_Down:
return GDK_Page_Down;
case GDK_KP_Delete:
return GDK_Delete;
case GDK_KP_Insert:
return GDK_Insert;
default:
return key_in;
}
}
/* central keypress event handler, almost all keypress events go to this function */
static gboolean on_key_press_event(GtkWidget *widget, GdkEventKey *ev, gpointer user_data)
{
@ -1095,12 +1139,14 @@ static gboolean on_key_press_event(GtkWidget *widget, GdkEventKey *ev, gpointer
keyval = ev->keyval;
state = ev->state & gtk_accelerator_get_default_mod_mask();
/* hack to get around that CTRL+Shift+r results in GDK_R not GDK_r */
if ((ev->state & GDK_SHIFT_MASK) || (ev->state & GDK_LOCK_MASK))
if (keyval >= GDK_A && keyval <= GDK_Z)
keyval += GDK_a - GDK_A;
if (keyval >= GDK_KP_Space && keyval < GDK_KP_Equal)
keyval = key_kp_translate(keyval);
/*geany_debug("%d (%d) %d (%d)", keyval, ev->keyval, state, ev->state);*/
/* special cases */
@ -1112,7 +1158,6 @@ static gboolean on_key_press_event(GtkWidget *widget, GdkEventKey *ev, gpointer
return TRUE;
if (check_menu_key(doc, keyval, state, ev->time))
return TRUE;
ignore_keybinding = FALSE;
for (g = 0; g < keybinding_groups->len; g++)
{
@ -1368,38 +1413,35 @@ static void cb_func_build_action(guint key_id)
if (!GTK_WIDGET_IS_SENSITIVE(ui_lookup_widget(main_widgets.window, "menu_build1")))
return;
menu_items = build_get_menu_items(doc->file_type->id);
/* TODO make it a table??*/
switch (key_id)
{
case GEANY_KEYS_BUILD_COMPILE:
item = menu_items->item_compile;
item = menu_items->menu_item[GEANY_GBG_FT][GBO_TO_CMD(GEANY_GBO_COMPILE)];
break;
case GEANY_KEYS_BUILD_LINK:
item = menu_items->item_link;
item = menu_items->menu_item[GEANY_GBG_FT][GBO_TO_CMD(GEANY_GBO_BUILD)];
break;
case GEANY_KEYS_BUILD_MAKE:
item = menu_items->item_make_all;
item = menu_items->menu_item[GEANY_GBG_NON_FT][GBO_TO_CMD(GEANY_GBO_MAKE_ALL)];
break;
case GEANY_KEYS_BUILD_MAKEOWNTARGET:
item = menu_items->item_make_custom;
item = menu_items->menu_item[GEANY_GBG_NON_FT][GBO_TO_CMD(GEANY_GBO_CUSTOM)];
break;
case GEANY_KEYS_BUILD_MAKEOBJECT:
item = menu_items->item_make_object;
item = menu_items->menu_item[GEANY_GBG_NON_FT][GBO_TO_CMD(GEANY_GBO_MAKE_OBJECT)];
break;
case GEANY_KEYS_BUILD_NEXTERROR:
item = menu_items->item_next_error;
item = menu_items->menu_item[GBG_FIXED][GBF_NEXT_ERROR];
break;
case GEANY_KEYS_BUILD_PREVIOUSERROR:
item = menu_items->item_previous_error;
item = menu_items->menu_item[GBG_FIXED][GBF_PREV_ERROR];
break;
case GEANY_KEYS_BUILD_RUN:
item = menu_items->item_exec;
break;
case GEANY_KEYS_BUILD_RUN2:
item = menu_items->item_exec2;
item = menu_items->menu_item[GEANY_GBG_EXEC][GBO_TO_CMD(GEANY_GBO_EXEC)];
break;
case GEANY_KEYS_BUILD_OPTIONS:
item = menu_items->item_set_args;
item = menu_items->menu_item[GBG_FIXED][GBF_COMMANDS];
break;
default:
item = NULL;
@ -2235,3 +2277,63 @@ static void cb_func_insert_action(guint key_id)
}
}
/* update key combination */
void keybindings_update_combo(GeanyKeyBinding *kb, guint key, GdkModifierType mods)
{
GtkWidget *widget = kb->menu_item;
if (widget && kb->key)
gtk_widget_remove_accelerator(widget, kb_accel_group, kb->key, kb->mods);
kb->key = key;
kb->mods = mods;
if (widget && kb->key)
gtk_widget_add_accelerator(widget, "activate", kb_accel_group,
kb->key, kb->mods, GTK_ACCEL_VISIBLE);
}
/* used for plugins */
GeanyKeyGroup *keybindings_set_group(GeanyKeyGroup *group, const gchar *section_name,
const gchar *label, gsize count, GeanyKeyGroupCallback callback)
{
g_return_val_if_fail(section_name, NULL);
g_return_val_if_fail(count, NULL);
g_return_val_if_fail(!callback, NULL);
/* prevent conflict with core bindings */
g_return_val_if_fail(!g_str_equal(section_name, keybindings_keyfile_group_name), NULL);
if (!group)
group = g_new0(GeanyKeyGroup, 1);
if (!group->keys || count > group->count)
{
/* allow resizing existing array of keys */
group->keys = g_renew(GeanyKeyBinding, group->keys, count);
memset(group->keys + group->count, 0, (count - group->count) * sizeof(GeanyKeyBinding));
}
group->plugin = TRUE;
add_kb_group(group, section_name, label, count, group->keys);
return group;
}
/* used for plugins */
void keybindings_free_group(GeanyKeyGroup *group)
{
GeanyKeyBinding *kb;
g_assert(group->plugin);
foreach_c_array(kb, group->keys, group->count)
{
g_free(kb->name);
g_free(kb->label);
}
g_free(group->keys);
g_ptr_array_remove_fast(keybinding_groups, group);
g_free(group);
}

View File

@ -31,32 +31,37 @@
#define GEANY_KEYBINDINGS_H 1
/** Function pointer type used for keybinding callbacks */
/** Function pointer type used for keybinding callbacks. */
typedef void (*GeanyKeyCallback) (guint key_id);
/** Represents a single keybinding action */
/* Note: name and label are not const strings so plugins can set them to malloc'd strings
* and free them in cleanup(). */
/** Represents a single keybinding action.
* Use keybindings_set_item() to set. */
typedef struct GeanyKeyBinding
{
guint key; /**< Key value in lower-case, such as @c GDK_a */
GdkModifierType mods; /**< Modifier keys, such as @c GDK_CONTROL_MASK */
guint key; /**< Key value in lower-case, such as @c GDK_a or 0 */
GdkModifierType mods; /**< Modifier keys, such as @c GDK_CONTROL_MASK or 0 */
gchar *name; /**< Key name for the configuration file, such as @c "menu_new" */
gchar *label; /**< Label used in the preferences dialog keybindings tab */
GeanyKeyCallback callback; /**< Callback function called when the key combination is pressed */
GtkWidget *menu_item; /**< Menu item widget for setting the menu accelerator */
} GeanyKeyBinding;
GeanyKeyCallback callback; /**< Function called when the key combination is pressed, or @c NULL */
GtkWidget *menu_item; /**< Optional widget to set an accelerator for, or @c NULL */
}
GeanyKeyBinding;
/** A collection of keybindings grouped together. */
typedef struct GeanyKeyGroup
typedef struct GeanyKeyGroup GeanyKeyGroup;
/* Plugins should not set these fields. */
#ifdef GEANY_PRIVATE
struct GeanyKeyGroup
{
const gchar *name; /**< Group name used in the configuration file, such as @c "html_chars" */
const gchar *label; /**< Group label used in the preferences dialog keybindings tab */
gsize count; /**< Count of GeanyKeyBinding structs in @c keys */
GeanyKeyBinding *keys; /**< Fixed array of GeanyKeyBinding structs */
}
GeanyKeyGroup;
const gchar *name; /* Group name used in the configuration file, such as @c "html_chars" */
const gchar *label; /* Group label used in the preferences dialog keybindings tab */
gsize count; /* number of keybindings the group holds */
GeanyKeyBinding *keys; /* array of GeanyKeyBinding structs */
gboolean plugin; /* used by plugin */
};
#endif
extern GPtrArray *keybinding_groups; /* array of GeanyKeyGroup pointers */
@ -293,7 +298,6 @@ enum
GEANY_KEYS_BUILD_NEXTERROR,
GEANY_KEYS_BUILD_PREVIOUSERROR,
GEANY_KEYS_BUILD_RUN,
GEANY_KEYS_BUILD_RUN2,
GEANY_KEYS_BUILD_OPTIONS,
GEANY_KEYS_BUILD_COUNT
};
@ -319,10 +323,22 @@ void keybindings_load_keyfile(void);
void keybindings_free(void);
void keybindings_set_item(GeanyKeyGroup *group, gsize key_id,
/** Function pointer type used for keybinding group callbacks. */
typedef gboolean (*GeanyKeyGroupCallback) (guint key_id);
GeanyKeyGroup *keybindings_set_group(GeanyKeyGroup *group, const gchar *section_name,
const gchar *label, gsize count, GeanyKeyGroupCallback callback) G_GNUC_WARN_UNUSED_RESULT;
void keybindings_free_group(GeanyKeyGroup *group);
GeanyKeyBinding *keybindings_set_item(GeanyKeyGroup *group, gsize key_id,
GeanyKeyCallback callback, guint key, GdkModifierType mod,
gchar *name, gchar *label, GtkWidget *menu_item);
GeanyKeyBinding *keybindings_get_item(GeanyKeyGroup *group, gsize key_id);
void keybindings_update_combo(GeanyKeyBinding *kb, guint key, GdkModifierType mods);
void keybindings_send_command(guint group_id, guint key_id);
GeanyKeyBinding *keybindings_lookup_item(guint group_id, guint key_id);

View File

@ -401,12 +401,14 @@ static void save_dialog_prefs(GKeyFile *config)
g_key_file_set_string(config, PACKAGE, "pref_template_datetime", template_prefs.datetime_format);
/* tools settings */
g_key_file_set_string(config, "tools", "make_cmd", tool_prefs.make_cmd ? tool_prefs.make_cmd : "");
g_key_file_set_string(config, "tools", "term_cmd", tool_prefs.term_cmd ? tool_prefs.term_cmd : "");
g_key_file_set_string(config, "tools", "browser_cmd", tool_prefs.browser_cmd ? tool_prefs.browser_cmd : "");
g_key_file_set_string(config, "tools", "grep_cmd", tool_prefs.grep_cmd ? tool_prefs.grep_cmd : "");
g_key_file_set_string(config, PACKAGE, "context_action_cmd", tool_prefs.context_action_cmd);
/* build menu */
build_save_menu( config, NULL, GEANY_BCS_PREF );
/* printing */
g_key_file_set_string(config, "printing", "print_cmd", printing_prefs.external_print_cmd ? printing_prefs.external_print_cmd : "");
g_key_file_set_boolean(config, "printing", "use_gtk_printing", printing_prefs.use_gtk_printing);
@ -764,13 +766,18 @@ static void load_dialog_prefs(GKeyFile *config)
template_prefs.datetime_format = utils_get_setting_string(config, PACKAGE, "pref_template_datetime", "%d.%m.%Y %H:%M:%S %Z");
/* tools */
tool_prefs.make_cmd = utils_get_setting_string(config, "tools", "make_cmd", GEANY_DEFAULT_TOOLS_MAKE);
tool_prefs.term_cmd = utils_get_setting_string(config, "tools", "term_cmd", GEANY_DEFAULT_TOOLS_TERMINAL);
tool_prefs.browser_cmd = utils_get_setting_string(config, "tools", "browser_cmd", GEANY_DEFAULT_TOOLS_BROWSER);
tool_prefs.grep_cmd = utils_get_setting_string(config, "tools", "grep_cmd", GEANY_DEFAULT_TOOLS_GREP);
tool_prefs.context_action_cmd = utils_get_setting_string(config, PACKAGE, "context_action_cmd", "");
/* build menu */
build_set_group_count( GEANY_GBG_FT, utils_get_setting_integer( config, "build-menu", "number_ft_menu_items", 0 ));
build_set_group_count( GEANY_GBG_NON_FT, utils_get_setting_integer( config, "build-menu", "number_non_ft_menu_items", 0 ));
build_set_group_count( GEANY_GBG_EXEC, utils_get_setting_integer( config, "build-menu", "number_exec_menu_items", 0 ));
build_load_menu( config, GEANY_BCS_PREF, NULL );
/* printing */
tmp_string2 = g_find_program_in_path(GEANY_DEFAULT_TOOLS_PRINTCMD);
#ifdef G_OS_WIN32
@ -1061,74 +1068,6 @@ void configuration_apply_settings(void)
}
#ifdef GEANY_DEBUG
/* Geany data file generation is only available with a debug build of Geany. */
static void generate_filetype_extensions(const gchar *output_dir);
/* Generate the config files in "data/" from defaults */
void configuration_generate_data_files(void)
{
gchar *cur_dir, *gen_dir;
cur_dir = g_get_current_dir();
gen_dir = g_strconcat(cur_dir, G_DIR_SEPARATOR_S, "data", NULL);
g_free(cur_dir);
if (! g_file_test(gen_dir, G_FILE_TEST_IS_DIR))
{
g_print("%s does not exist!\n", gen_dir);
return;
}
g_print("Generating system files in %s:\n", gen_dir);
/* currently only filetype extensions are auto-generated. */
generate_filetype_extensions(gen_dir);
g_free(gen_dir);
}
/* This will write the default settings for the system filetype_extensions.conf */
static void generate_filetype_extensions(const gchar *output_dir)
{
guint i;
gchar *configfile = g_strconcat(output_dir, G_DIR_SEPARATOR_S, "filetype_extensions.conf", NULL);
gchar *data, *basename;
GKeyFile *config;
config = g_key_file_new();
g_key_file_set_comment(config, NULL, NULL,
"*** This file generated by: geany --generate-data-files ***", NULL);
/* add filetype keys */
for (i = 0; i < filetypes_array->len; i++)
{
g_key_file_set_string_list(config, "Extensions", filetypes[i]->name,
(const gchar**) filetypes[i]->pattern, g_strv_length(filetypes[i]->pattern));
}
/* add comment */
g_key_file_set_comment(config, "Extensions", NULL,
"Filetype extension configuration file for Geany\n"
"Insert as many items as you want, seperate them with a \";\".\n"
"See Geany's main documentation for details.", NULL);
/* write the file */
g_print("%s: ", G_STRFUNC);
data = g_key_file_to_data(config, NULL, NULL);
basename = g_path_get_basename(configfile);
if (utils_write_file(configfile, data) == 0)
g_print("wrote file %s.\n", basename);
else
g_print("*** ERROR: error writing file %s\n", basename);
g_free(basename);
g_free(data);
g_key_file_free(config);
}
#endif
void configuration_init(void)
{
keyfile_groups = g_ptr_array_new();

View File

@ -55,9 +55,4 @@ void configuration_save_session_files(GKeyFile *config);
* realisation of the main window */
void configuration_apply_settings(void);
#ifdef GEANY_DEBUG
/* Generate the config files in "data/" from defaults */
void configuration_generate_data_files(void);
#endif
#endif

View File

@ -108,7 +108,6 @@ static gchar *alternate_config = NULL;
static gboolean no_vte = FALSE;
static gchar *lib_vte = NULL;
#endif
static gboolean generate_datafiles = FALSE;
static gboolean generate_tags = FALSE;
static gboolean no_preprocessing = FALSE;
static gboolean ft_names = FALSE;
@ -127,7 +126,6 @@ static GOptionEntry entries[] =
{ "ft-names", 0, 0, G_OPTION_ARG_NONE, &ft_names, N_("Print internal filetype names"), NULL },
{ "generate-tags", 'g', 0, G_OPTION_ARG_NONE, &generate_tags, N_("Generate global tags file (see documentation)"), NULL },
{ "no-preprocessing", 'P', 0, G_OPTION_ARG_NONE, &no_preprocessing, N_("Don't preprocess C/C++ files when generating tags"), NULL },
{ "generate-data-files", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &generate_datafiles, NULL, NULL },
#ifdef HAVE_SOCKET
{ "new-instance", 'i', 0, G_OPTION_ARG_NONE, &cl_options.new_instance, N_("Don't open files in a running instance, force opening a new instance"), NULL },
#endif
@ -138,7 +136,7 @@ static GOptionEntry entries[] =
{ "no-plugins", 'p', 0, G_OPTION_ARG_NONE, &no_plugins, N_("Don't load plugins"), NULL },
#endif
{ "print-prefix", 0, 0, G_OPTION_ARG_NONE, &print_prefix, N_("Print Geany's installation prefix"), NULL },
{ "no-session", 's', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &cl_options.load_session, N_("don't load the previous session's files"), NULL },
{ "no-session", 's', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &cl_options.load_session, N_("Don't load the previous session's files"), NULL },
#ifdef HAVE_VTE
{ "no-terminal", 't', 0, G_OPTION_ARG_NONE, &no_vte, N_("Don't load terminal support"), NULL },
{ "vte-lib", 0, 0, G_OPTION_ARG_FILENAME, &lib_vte, N_("Filename of libvte.so"), NULL },
@ -523,14 +521,6 @@ static void parse_command_line_options(gint *argc, gchar ***argv)
app->configdir = g_build_filename(g_get_user_config_dir(), "geany", NULL);
}
#ifdef GEANY_DEBUG
if (generate_datafiles)
{
filetypes_init_types();
configuration_generate_data_files(); /* currently only filetype_extensions.conf */
exit(0);
}
#endif
if (generate_tags)
{
gboolean ret;
@ -1123,7 +1113,6 @@ void main_quit()
g_free(template_prefs.mail);
g_free(template_prefs.initials);
g_free(template_prefs.version);
g_free(tool_prefs.make_cmd);
g_free(tool_prefs.term_cmd);
g_free(tool_prefs.browser_cmd);
g_free(tool_prefs.grep_cmd);

View File

@ -1,6 +1,7 @@
# Note: PACKAGE_DATA_DIR and PACKAGE_LOCALE_DIR are no longer used on Windows.
DEFINES = -DHAVE_CONFIG_H \
-DGEANY_PRIVATE \
-DGEANY_DATADIR=\"data\" \
-DGEANY_LOCALEDIR=\"\" \
-DGEANY_LIBDIR=\"\" \

View File

@ -267,9 +267,9 @@ void msgwin_compiler_add_string(gint msg_color, const gchar *msg)
gtk_tree_path_free(path);
}
/* calling build_menu_update for every build message would be overkill */
gtk_widget_set_sensitive(build_get_menu_items(-1)->item_next_error, TRUE);
gtk_widget_set_sensitive(build_get_menu_items(-1)->item_previous_error, TRUE);
/* calling build_menu_update for every build message would be overkill, TODO really should call it once when all done */
gtk_widget_set_sensitive(build_get_menu_items(-1)->menu_item[GBG_FIXED][GBF_NEXT_ERROR], TRUE);
gtk_widget_set_sensitive(build_get_menu_items(-1)->menu_item[GBG_FIXED][GBF_PREV_ERROR], TRUE);
}

View File

@ -50,13 +50,13 @@
enum {
/** The Application Programming Interface (API) version, incremented
* whenever any plugin data types are modified or appended to. */
GEANY_API_VERSION = 150,
GEANY_API_VERSION = 153,
/** The Application Binary Interface (ABI) version, incremented whenever
* existing fields in the plugin data types have to be changed or reordered. */
/* This should usually stay the same if fields are only appended, assuming only pointers to
* structs and not structs themselves are declared by plugins. */
GEANY_ABI_VERSION = 63
GEANY_ABI_VERSION = 65
};
/** Check the plugin can be loaded by Geany.
@ -119,23 +119,32 @@ GeanyPlugin;
}
/** @see PLUGIN_KEY_GROUP() macro. */
typedef struct GeanyKeyGroupInfo
{
const gchar *name; /**< Group name used in the configuration file, such as @c "html_chars" */
gsize count; /**< The number of keybindings the group will hold */
}
GeanyKeyGroupInfo;
/** Declare and initialise a keybinding group.
* @code GeanyKeyGroup plugin_key_group[1]; @endcode
* You must then set the @c plugin_key_group::keys[] entries for the group in plugin_init().
* @code GeanyKeyGroup *plugin_key_group; @endcode
* You must then set the @c plugin_key_group::keys[] entries for the group in plugin_init(),
* normally using keybindings_set_item().
* The @c plugin_key_group::label field is set by Geany after @c plugin_init()
* is called, to the name of the plugin.
* @param group_name A unique group name (without quotes) to be used in the
* configuration file, such as @c html_chars.
* @param key_count The number of keybindings the group will hold. */
* @param key_count The number of keybindings the group will hold.
* @see plugin_set_key_group() to set the group size dynamically. */
#define PLUGIN_KEY_GROUP(group_name, key_count) \
static GeanyKeyBinding plugin_keys[key_count]; \
\
/* We have to declare plugin_key_group as a single element array.
/* We have to declare this as a single element array.
* Declaring as a pointer to a struct doesn't work with g_module_symbol(). */ \
GeanyKeyGroup plugin_key_group[1] = \
GeanyKeyGroupInfo plugin_key_group_info[1] = \
{ \
{G_STRINGIFY(group_name), NULL, key_count, plugin_keys} \
};
{G_STRINGIFY(group_name), key_count} \
};\
GeanyKeyGroup *plugin_key_group = NULL;
/** Callback array entry type used with the @ref plugin_callbacks symbol. */
@ -225,7 +234,7 @@ typedef struct GeanyFunctions
struct NavQueueFuncs *p_navqueue; /**< See navqueue.h */
struct EditorFuncs *p_editor; /**< See editor.h */
struct MainFuncs *p_main; /**< See main.h */
struct PluginFuncs *p_plugin; /**< See plugins.c */
struct PluginFuncs *p_plugin; /**< See pluginutils.c */
struct ScintillaFuncs *p_scintilla; /**< See ScintillaFuncs */
struct MsgWinFuncs *p_msgwin; /**< See msgwindow.h */
}
@ -462,9 +471,11 @@ typedef void (*_GeanyKeyCallback) (guint key_id);
typedef struct KeybindingFuncs
{
void (*send_command) (guint group_id, guint key_id);
void (*set_item) (struct GeanyKeyGroup *group, gsize key_id,
struct GeanyKeyBinding* (*set_item) (struct GeanyKeyGroup *group, gsize key_id,
_GeanyKeyCallback callback, guint key, GdkModifierType mod,
gchar *name, gchar *label, GtkWidget *menu_item);
struct GeanyKeyBinding* (*get_item)(struct GeanyKeyGroup *group, gsize key_id);
}
KeybindingFuncs;
@ -541,7 +552,10 @@ typedef struct EditorFuncs
EditorFuncs;
/* See plugins.c */
/* avoid including keybindings.h */
typedef gboolean (*_GeanyKeyGroupCallback) (guint key_id);
/* See pluginutils.c */
typedef struct PluginFuncs
{
void (*add_toolbar_item)(GeanyPlugin *plugin, GtkToolItem *item);
@ -549,6 +563,8 @@ typedef struct PluginFuncs
void (*signal_connect) (GeanyPlugin *plugin,
GObject *object, gchar *signal_name, gboolean after,
GCallback callback, gpointer user_data);
struct GeanyKeyGroup* (*set_key_group)(GeanyPlugin *plugin,
const gchar *section_name, gsize count, _GeanyKeyGroupCallback callback);
}
PluginFuncs;
@ -556,7 +572,8 @@ PluginFuncs;
/* Deprecated aliases */
#ifndef GEANY_DISABLE_DEPRECATED
/** @c NULL-safe way to get the index of @a doc_ptr in the documents array. */
/** @deprecated - copy into your plugin code if needed.
* @c NULL-safe way to get the index of @a doc_ptr in the documents array. */
#define DOC_IDX(doc_ptr) \
(doc_ptr ? doc_ptr->index : -1)
#define DOC_IDX_VALID(doc_idx) \

View File

@ -26,7 +26,9 @@
#ifndef PLUGINPRIVATE_H
#define PLUGINPRIVATE_H
#include "ui_utils.h"
#include "ui_utils.h" /* GeanyAutoSeparator */
#include "keybindings.h" /* GeanyKeyGroup */
typedef struct SignalConnection
{
@ -35,10 +37,23 @@ typedef struct SignalConnection
}
SignalConnection;
typedef struct GeanyPluginPrivate
{
GModule *module;
gchar *filename; /* plugin filename (/path/libname.so) */
PluginInfo info; /* plugin name, description, etc */
GeanyPlugin public; /* fields the plugin can read */
void (*init) (GeanyData *data); /* Called when the plugin is enabled */
GtkWidget* (*configure) (GtkDialog *dialog); /* plugin configure dialog, optional */
void (*help) (void); /* Called when the plugin should show some help, optional */
void (*cleanup) (void); /* Called when the plugin is disabled or when Geany exits */
/* extra stuff */
PluginFields fields;
GeanyKeyGroup *key_group;
GeanyAutoSeparator toolbar_separator;
gboolean resident;
GArray *signal_ids; /* SignalConnection's to disconnect when unloading */
}
GeanyPluginPrivate;

View File

@ -62,24 +62,7 @@
#include "pluginutils.h"
#include "pluginprivate.h"
typedef struct Plugin
{
GModule *module;
gchar *filename; /* plugin filename (/path/libname.so) */
PluginInfo info; /* plugin name, description, etc */
PluginFields fields;
GeanyPlugin public; /* fields the plugin can read */
GeanyPluginPrivate priv; /* GeanyPlugin type private data, same as (*public.priv) */
GeanyKeyGroup *key_group;
void (*init) (GeanyData *data); /* Called when the plugin is enabled */
GtkWidget* (*configure) (GtkDialog *dialog); /* plugin configure dialog, optional */
void (*help) (void); /* Called when the plugin should show some help, optional */
void (*cleanup) (void); /* Called when the plugin is disabled or when Geany exits */
}
Plugin;
typedef GeanyPluginPrivate Plugin; /* shorter alias */
static gboolean want_plugins = FALSE;
@ -99,7 +82,8 @@ static void pm_show_dialog(GtkMenuItem *menuitem, gpointer user_data);
static PluginFuncs plugin_funcs = {
&plugin_add_toolbar_item,
&plugin_module_make_resident,
&plugin_signal_connect
&plugin_signal_connect,
&plugin_set_key_group
};
static DocumentFuncs doc_funcs = {
@ -259,7 +243,8 @@ static EncodingFuncs encoding_funcs = {
static KeybindingFuncs keybindings_funcs = {
&keybindings_send_command,
&keybindings_set_item
&keybindings_set_item,
&keybindings_get_item
};
static TagManagerFuncs tagmanager_funcs = {
@ -464,42 +449,40 @@ static void add_callbacks(Plugin *plugin, PluginCallback *callbacks)
}
static void
add_kb_group(Plugin *plugin)
static void read_key_group(Plugin *plugin)
{
guint i;
GeanyKeyGroupInfo *p_key_info;
GeanyKeyGroup **p_key_group;
if (!NZV(plugin->key_group->name))
g_module_symbol(plugin->module, "plugin_key_group_info", (void *) &p_key_info);
g_module_symbol(plugin->module, "plugin_key_group", (void *) &p_key_group);
if (p_key_info && p_key_group)
{
geany_debug("Plugin \"%s\" has not set a name for its keybinding group"
" - ignoring all keybindings!",
GeanyKeyGroupInfo *key_info = p_key_info;
if (*p_key_group)
geany_debug("Ignoring plugin_key_group symbol for plugin '%s' - "
"use plugin_set_key_group() instead to allocate keybindings dynamically.",
plugin->info.name);
return;
}
g_return_if_fail(! g_str_equal(plugin->key_group->name, keybindings_keyfile_group_name));
for (i = 0; i < plugin->key_group->count; i++)
else
{
GeanyKeyBinding *kb = &plugin->key_group->keys[i];
if (!NZV(kb->name))
if (key_info->count)
{
geany_debug("Plugin \"%s\" has not set a name for keybinding %d"
" - ignoring all keybindings!",
plugin->info.name, i);
plugin->key_group->count = 0;
break;
GeanyKeyGroup *key_group =
plugin_set_key_group(&plugin->public, key_info->name, key_info->count, NULL);
if (key_group)
*p_key_group = key_group;
}
else
geany_debug("Ignoring plugin_key_group_info symbol for plugin '%s' - "
"count field is zero. Maybe use plugin_set_key_group() instead?",
plugin->info.name);
}
}
if (plugin->key_group->count == 0)
{
plugin->key_group = NULL; /* Ignore the group (maybe the plugin has optional KB) */
return;
}
plugin->key_group->label = plugin->info.name;
g_ptr_array_add(keybinding_groups, plugin->key_group);
else if (p_key_info || p_key_group)
geany_debug("Ignoring only one of plugin_key_group[_info] symbols defined for plugin '%s'. "
"Maybe use plugin_set_key_group() instead?",
plugin->info.name);
}
@ -529,14 +512,12 @@ plugin_init(Plugin *plugin)
g_module_symbol(plugin->module, "plugin_fields", (void *) &plugin_fields);
if (plugin_fields)
*plugin_fields = &plugin->fields;
read_key_group(plugin);
/* start the plugin */
g_return_if_fail(plugin->init);
plugin->init(&geany_data);
if (p_geany_plugin && (*p_geany_plugin)->priv->resident)
g_module_make_resident(plugin->module);
/* store some function pointers for later use */
g_module_symbol(plugin->module, "plugin_configure", (void *) &plugin->configure);
g_module_symbol(plugin->module, "plugin_help", (void *) &plugin->help);
@ -559,10 +540,6 @@ plugin_init(Plugin *plugin)
if (callbacks)
add_callbacks(plugin, callbacks);
g_module_symbol(plugin->module, "plugin_key_group", (void *) &plugin->key_group);
if (plugin->key_group)
add_kb_group(plugin);
/* remember which plugins are active */
active_plugin_list = g_list_append(active_plugin_list, plugin);
@ -667,7 +644,7 @@ plugin_new(const gchar *fname, gboolean init_plugin, gboolean add_to_list)
plugin->filename = g_strdup(fname);
plugin->module = module;
plugin->public.info = &plugin->info;
plugin->public.priv = &plugin->priv;
plugin->public.priv = plugin;
if (init_plugin)
plugin_init(plugin);
@ -681,7 +658,7 @@ plugin_new(const gchar *fname, gboolean init_plugin, gboolean add_to_list)
static void remove_callbacks(Plugin *plugin)
{
GArray *signal_ids = plugin->priv.signal_ids;
GArray *signal_ids = plugin->signal_ids;
SignalConnection *sc;
if (signal_ids == NULL)
@ -712,9 +689,9 @@ plugin_cleanup(Plugin *plugin)
remove_callbacks(plugin);
if (plugin->key_group)
g_ptr_array_remove_fast(keybinding_groups, plugin->key_group);
keybindings_free_group(plugin->key_group);
widget = plugin->priv.toolbar_separator.widget;
widget = plugin->toolbar_separator.widget;
if (widget)
gtk_widget_destroy(widget);

View File

@ -27,11 +27,13 @@
* These functions all take the @ref geany_plugin symbol as their first argument. */
#include "geany.h"
#include "pluginutils.h"
#include "pluginprivate.h"
#include "ui_utils.h"
#include "toolbar.h"
#include "utils.h"
/** Insert a toolbar item before the Quit button, or after the previous plugin toolbar item.
@ -88,7 +90,7 @@ void plugin_module_make_resident(GeanyPlugin *plugin)
{
g_return_if_fail(plugin);
plugin->priv->resident = TRUE;
g_module_make_resident(plugin->priv->module);
}
@ -125,3 +127,22 @@ void plugin_signal_connect(GeanyPlugin *plugin,
}
/** Setup or resize a keybinding group for the plugin.
* You should then call keybindings_set_item() for each keybinding in the group.
* @param plugin Must be @ref geany_plugin.
* @param section_name Name used in the configuration file, such as @c "html_chars".
* @param count Number of keybindings for the group.
* @param callback Unused, must be @c NULL.
* @return The plugin's keybinding group.
* @since 0.19. */
GeanyKeyGroup *plugin_set_key_group(GeanyPlugin *plugin,
const gchar *section_name, gsize count, GeanyKeyGroupCallback callback)
{
GeanyPluginPrivate *priv = plugin->priv;
priv->key_group = keybindings_set_group(priv->key_group, section_name,
priv->info.name, count, callback);
return priv->key_group;
}

View File

@ -26,7 +26,9 @@
#ifndef PLUGINUTILS_H
#define PLUGINUTILS_H
#include "plugindata.h"
#include "plugindata.h" /* GeanyPlugin */
#include "keybindings.h" /* GeanyKeyGroupCallback */
void plugin_add_toolbar_item(GeanyPlugin *plugin, GtkToolItem *item);
@ -36,4 +38,7 @@ void plugin_signal_connect(GeanyPlugin *plugin,
GObject *object, gchar *signal_name, gboolean after,
GCallback callback, gpointer user_data);
struct GeanyKeyGroup *plugin_set_key_group(GeanyPlugin *plugin,
const gchar *section_name, gsize count, GeanyKeyGroupCallback callback);
#endif /* PLUGINUTILS_H */

View File

@ -587,8 +587,6 @@ static void prefs_init_dialog(void)
(editor_prefs.autoclose_chars & GEANY_AC_DQUOTE));
/* Tools Settings */
if (tool_prefs.make_cmd)
gtk_entry_set_text(GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_com_make")), tool_prefs.make_cmd);
if (tool_prefs.term_cmd)
gtk_entry_set_text(GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_com_term")), tool_prefs.term_cmd);
@ -979,9 +977,6 @@ on_prefs_button_clicked(GtkDialog *dialog, gint response, gpointer user_data)
| (autoclose_brackets[4] ? GEANY_AC_DQUOTE : 0);
/* Tools Settings */
widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_com_make");
g_free(tool_prefs.make_cmd);
tool_prefs.make_cmd = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_com_term");
g_free(tool_prefs.term_cmd);
@ -1109,6 +1104,8 @@ on_prefs_button_clicked(GtkDialog *dialog, gint response, gpointer user_data)
toolbar_apply_settings();
toolbar_update_ui();
toolbar_show_hide();
if (interface_prefs.sidebar_openfiles_visible || interface_prefs.sidebar_symbol_visible)
ui_prefs.sidebar_visible = TRUE;
ui_sidebar_show_hide();
gtk_notebook_set_show_tabs(GTK_NOTEBOOK(main_widgets.notebook), interface_prefs.show_notebook_tabs);
@ -1270,8 +1267,7 @@ static void kb_cell_edited_cb(GtkCellRendererText *cellrenderertext, gchar *path
/* set the values here, because of the above check, setting it in
* gtk_accelerator_parse would return a wrong key combination if it is duplicate */
kb->key = lkey;
kb->mods = lmods;
keybindings_update_combo(kb, lkey, lmods);
gtk_tree_store_set(store, &iter, KB_TREE_SHORTCUT, new_text, -1);
@ -1316,8 +1312,7 @@ static void kb_dialog_response_cb(GtkWidget *dialog, gint response, G_GNUC_UNUSE
/* set the values here, because of the above check, setting it in
* gtk_accelerator_parse would return a wrong key combination if it is duplicate */
kb->key = lkey;
kb->mods = lmods;
keybindings_update_combo(kb, lkey, lmods);
gtk_tree_store_set(store, &g_iter,
KB_TREE_SHORTCUT, gtk_label_get_text(GTK_LABEL(dialog_label)), -1);
@ -1400,8 +1395,7 @@ static gboolean kb_find_duplicate(GeanyKeyBinding *search_kb,
_("The combination '%s' is already used for \"%s\"."),
action, kb->label))
{
kb->key = 0;
kb->mods = 0;
keybindings_update_combo(kb, 0, 0);
kb_clear_tree_shortcut(g, i);
continue;
}
@ -1549,7 +1543,7 @@ void prefs_show_dialog(void)
ui_entry_add_clear_icon(ui_lookup_widget(ui_widgets.prefs_dialog, "project_file_path_entry"));
ui_entry_add_clear_icon(ui_lookup_widget(ui_widgets.prefs_dialog, "extra_plugin_path_entry"));
ui_entry_add_clear_icon(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_toggle_mark"));
ui_entry_add_clear_icon(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_com_make"));
/* ui_entry_add_clear_icon(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_com_make")); */
ui_entry_add_clear_icon(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_com_term"));
ui_entry_add_clear_icon(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_browser"));
ui_entry_add_clear_icon(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_grep"));
@ -1587,9 +1581,9 @@ void prefs_show_dialog(void)
"font-set", G_CALLBACK(on_prefs_font_choosed), GINT_TO_POINTER(3));
g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "long_line_color"),
"color-set", G_CALLBACK(on_prefs_color_choosed), GINT_TO_POINTER(1));
/* file chooser buttons in the tools tab */
/* file chooser buttons in the tools tab
g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "button_make"),
"clicked", G_CALLBACK(on_prefs_tools_button_clicked), ui_lookup_widget(ui_widgets.prefs_dialog, "entry_com_make"));
"clicked", G_CALLBACK(on_prefs_tools_button_clicked), ui_lookup_widget(ui_widgets.prefs_dialog, "entry_com_make")); */
g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "button_term"),
"clicked", G_CALLBACK(on_prefs_tools_button_clicked), ui_lookup_widget(ui_widgets.prefs_dialog, "entry_com_term"));
g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "button_browser"),

View File

@ -46,7 +46,6 @@ extern GeanyPrefs prefs;
typedef struct GeanyToolPrefs
{
gchar *browser_cmd;
gchar *make_cmd;
gchar *term_cmd;
gchar *grep_cmd;
gchar *context_action_cmd;

View File

@ -49,6 +49,7 @@
#include "editor.h"
#include "stash.h"
#include "treeviews.h"
#include "filetypes.h"
ProjectPrefs project_prefs = { NULL, FALSE, FALSE };
@ -75,16 +76,14 @@ typedef struct _PropertyDialogElements
GtkWidget *description;
GtkWidget *file_name;
GtkWidget *base_path;
GtkWidget *make_in_base_path;
GtkWidget *run_cmd;
GtkWidget *patterns;
TableData build_properties;
} PropertyDialogElements;
static gboolean update_config(const PropertyDialogElements *e);
static void on_file_save_button_clicked(GtkButton *button, PropertyDialogElements *e);
static void on_file_open_button_clicked(GtkButton *button, PropertyDialogElements *e);
static gboolean load_config(const gchar *filename);
static gboolean write_config(gboolean emit_signal);
static void on_name_entry_changed(GtkEditable *editable, PropertyDialogElements *e);
@ -322,6 +321,17 @@ static void update_ui(void)
}
static void remove_foreach_project_filetype( gpointer data, gpointer user_data )
{
GeanyFiletype *ft = (GeanyFiletype*)data;
if (ft!=NULL)
{
setptr( ft->projfilecmds, NULL);
setptr(ft->projerror_regex_string, NULL);
ft->project_list_entry = -1;
}
}
/* open_default will make function reload default session files on close */
void project_close(gboolean open_default)
{
@ -332,11 +342,24 @@ void project_close(gboolean open_default)
/* use write_config() to save project session files */
write_config(FALSE);
/* remove project filetypes build entries */
if (app->project->build_filetypes_list!=NULL)
{
g_ptr_array_foreach( app->project->build_filetypes_list, remove_foreach_project_filetype, NULL );
g_ptr_array_free(app->project->build_filetypes_list, FALSE);
}
/* remove project non filetype build menu items */
build_remove_menu_item( GEANY_BCS_PROJ, GEANY_GBG_NON_FT, -1 );
build_remove_menu_item( GEANY_BCS_PROJ, GEANY_GBG_EXEC, -1 );
/* remove project regexen */
setptr(regex_proj, NULL);
g_free(app->project->name);
g_free(app->project->description);
g_free(app->project->file_name);
g_free(app->project->base_path);
g_free(app->project->run_cmd);
g_free(app->project);
app->project = NULL;
@ -360,15 +383,22 @@ void project_close(gboolean open_default)
update_ui();
}
static void on_set_use_base_path_clicked( GtkWidget *unused1, gpointer user_data )
{
TableData td = (TableData)user_data;
build_set_non_ft_wd_to_proj(td);
}
static void create_properties_dialog(PropertyDialogElements *e)
{
GtkWidget *table, *notebook;
GtkWidget *image;
GtkWidget *table, *notebook, *build_table;
GtkWidget *button;
GtkWidget *bbox;
GtkWidget *label;
GtkWidget *swin;
GeanyDocument *doc = document_get_current();
GeanyFiletype *ft;
e->dialog = create_project_dialog();
gtk_window_set_transient_for(GTK_WINDOW(e->dialog), GTK_WINDOW(main_widgets.window));
@ -387,7 +417,7 @@ static void create_properties_dialog(PropertyDialogElements *e)
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
gtk_misc_set_alignment(GTK_MISC(label), -1, 0);
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
e->name = gtk_entry_new();
ui_entry_add_clear_icon(e->name);
@ -400,7 +430,7 @@ static void create_properties_dialog(PropertyDialogElements *e)
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
gtk_misc_set_alignment(GTK_MISC(label), -1, 0);
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
e->file_name = gtk_entry_new();
ui_entry_add_clear_icon(e->file_name);
@ -413,7 +443,7 @@ static void create_properties_dialog(PropertyDialogElements *e)
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 2, 3,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (GTK_FILL), 0, 0);
gtk_misc_set_alignment(GTK_MISC(label), -1, 0);
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
e->description = gtk_text_view_new();
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(e->description), GTK_WRAP_WORD);
@ -430,7 +460,7 @@ static void create_properties_dialog(PropertyDialogElements *e)
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 3, 4,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
gtk_misc_set_alignment(GTK_MISC(label), -1, 0);
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
e->base_path = gtk_entry_new();
ui_entry_add_clear_icon(e->base_path);
@ -444,33 +474,27 @@ static void create_properties_dialog(PropertyDialogElements *e)
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
e->make_in_base_path = gtk_check_button_new_with_label(_("Make in base path"));
gtk_table_attach(GTK_TABLE(table), e->make_in_base_path, 0, 3, 4, 5,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
if (doc!=NULL) ft=doc->file_type;
build_table = build_commands_table( doc, GEANY_BCS_PROJ, &(e->build_properties), ft );
label = gtk_label_new(_("Build"));
notebook = ui_lookup_widget(e->dialog, "project_notebook");
gtk_notebook_insert_page(GTK_NOTEBOOK(notebook), build_table, label, 2);
label = gtk_label_new(_("Run command:"));
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 5, 6,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
gtk_misc_set_alignment(GTK_MISC(label), -1, 0);
label = gtk_label_new(_("Set the non-filetype working directories on build tab to use base path:"));
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
e->run_cmd = gtk_entry_new();
ui_entry_add_clear_icon(e->run_cmd);
ui_widget_set_tooltip_text(e->run_cmd,
_("Command-line to run in the project base directory. "
"Options can be appended to the command. "
"Leave blank to use the default run command."));
button = gtk_button_new();
g_signal_connect(button, "clicked", G_CALLBACK(on_file_open_button_clicked), e);
image = gtk_image_new_from_stock("gtk-open", GTK_ICON_SIZE_BUTTON);
gtk_container_add(GTK_CONTAINER(button), image);
button = gtk_button_new_with_label(_("Set"));
ui_widget_set_tooltip_text(button,
_("Set the working directories (on the Build tab) "
"for the non-filetype build commands to use the base path"));
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
g_signal_connect(button, "clicked", G_CALLBACK(on_set_use_base_path_clicked), e->build_properties);
bbox = gtk_hbox_new(FALSE, 6);
gtk_box_pack_start_defaults(GTK_BOX(bbox), e->run_cmd);
gtk_box_pack_start(GTK_BOX(bbox), label, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
gtk_table_attach(GTK_TABLE(table), bbox, 1, 2, 5, 6,
gtk_table_attach(GTK_TABLE(table), bbox, 0, 2, 4, 5,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
(GtkAttachOptions) (GTK_FILL), 0, 0);
#if 0
label = gtk_label_new(_("File patterns:"));
@ -478,7 +502,7 @@ static void create_properties_dialog(PropertyDialogElements *e)
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 6, 7,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (GTK_FILL), 0, 0);
gtk_misc_set_alignment(GTK_MISC(label), -1, 0);
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
e->patterns = gtk_text_view_new();
swin = gtk_scrolled_window_new(NULL, NULL);
@ -491,7 +515,6 @@ static void create_properties_dialog(PropertyDialogElements *e)
(GtkAttachOptions) (0), 0, 0);
#endif
notebook = ui_lookup_widget(e->dialog, "project_notebook");
label = gtk_label_new(_("Project"));
gtk_widget_show(table); /* needed to switch current page */
gtk_notebook_insert_page(GTK_NOTEBOOK(notebook), table, label, 0);
@ -545,11 +568,6 @@ void project_properties(void)
gtk_entry_set_text(GTK_ENTRY(e->file_name), p->file_name);
gtk_entry_set_text(GTK_ENTRY(e->base_path), p->base_path);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(e->make_in_base_path),
p->make_in_base_path);
if (p->run_cmd != NULL)
gtk_entry_set_text(GTK_ENTRY(e->run_cmd), p->run_cmd);
gtk_widget_show_all(e->dialog);
retry:
@ -562,6 +580,7 @@ void project_properties(void)
stash_group_update(indent_group, e->dialog);
}
build_free_fields( e->build_properties );
gtk_widget_destroy(e->dialog);
g_free(e);
}
@ -701,12 +720,11 @@ static gboolean update_config(const PropertyDialogElements *e)
if (! new_project) /* save properties specific fields */
{
GtkTextIter start, end;
/*gchar *tmp;*/
GtkTextBuffer *buffer;
p->make_in_base_path = gtk_toggle_button_get_active(
GTK_TOGGLE_BUTTON(e->make_in_base_path));
setptr(p->run_cmd, g_strdup(gtk_entry_get_text(GTK_ENTRY(e->run_cmd))));
GeanyDocument *doc = document_get_current();
BuildDestination menu_dst;
GeanyBuildCommand *oldvalue;
GeanyFiletype *ft=NULL;
/* get and set the project description */
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(e->description));
@ -714,6 +732,32 @@ static gboolean update_config(const PropertyDialogElements *e)
gtk_text_buffer_get_end_iter(buffer, &end);
setptr(p->description, g_strdup(gtk_text_buffer_get_text(buffer, &start, &end, FALSE)));
/* read the project build menu */
if ( doc!=NULL )ft=doc->file_type;
if ( ft!=NULL )
{
menu_dst.dst[GEANY_GBG_FT] = &(ft->projfilecmds);
oldvalue = ft->projfilecmds;
menu_dst.fileregexstr = &(ft->projerror_regex_string);
}
else
{
menu_dst.dst[GEANY_GBG_FT] = NULL;
oldvalue = NULL;
menu_dst.fileregexstr = NULL;
}
menu_dst.dst[GEANY_GBG_NON_FT] = &non_ft_proj;
menu_dst.dst[GEANY_GBG_EXEC] = &exec_proj;
menu_dst.nonfileregexstr = &regex_proj;
build_read_commands( &menu_dst, e->build_properties, GTK_RESPONSE_ACCEPT );
if (ft!=NULL && ft->projfilecmds!=oldvalue && ft->project_list_entry<0)
{
if (p->build_filetypes_list==NULL)p->build_filetypes_list = g_ptr_array_new();
ft->project_list_entry = p->build_filetypes_list->len;
g_ptr_array_add(p->build_filetypes_list, ft);
}
build_menu_update(doc);
#if 0
/* get and set the project file patterns */
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(e->patterns));
@ -821,35 +865,6 @@ static void on_file_save_button_clicked(GtkButton *button, PropertyDialogElement
}
static void on_file_open_button_clicked(GtkButton *button, PropertyDialogElements *e)
{
#ifdef G_OS_WIN32
gchar *path = win32_show_project_open_dialog(e->dialog, _("Choose Project Run Command"),
gtk_entry_get_text(GTK_ENTRY(e->run_cmd)), FALSE, FALSE);
if (path != NULL)
{
gtk_entry_set_text(GTK_ENTRY(e->run_cmd), path);
g_free(path);
}
#else
GtkWidget *dialog;
/* initialise the dialog */
dialog = gtk_file_chooser_dialog_new(_("Choose Project Run Command"), NULL,
GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
gtk_widget_set_name(dialog, "GeanyDialog");
gtk_window_set_destroy_with_parent(GTK_WINDOW(dialog), TRUE);
gtk_window_set_skip_taskbar_hint(GTK_WINDOW(dialog), TRUE);
gtk_window_set_type_hint(GTK_WINDOW(dialog), GDK_WINDOW_TYPE_HINT_DIALOG);
gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
run_dialog(dialog, e->run_cmd);
#endif
}
/* sets the project base path and the project file name according to the project name */
static void on_name_entry_changed(GtkEditable *editable, PropertyDialogElements *e)
{
@ -948,10 +963,9 @@ static gboolean load_config(const gchar *filename)
p->description = utils_get_setting_string(config, "project", "description", "");
p->file_name = utils_get_utf8_from_locale(filename);
p->base_path = utils_get_setting_string(config, "project", "base_path", "");
p->make_in_base_path = utils_get_setting_boolean(config, "project", "make_in_base_path", TRUE);
p->run_cmd = utils_get_setting_string(config, "project", "run_cmd", "");
p->file_patterns = g_key_file_get_string_list(config, "project", "file_patterns", NULL, NULL);
build_load_menu( config, GEANY_BCS_PROJ, (gpointer)p );
if (project_prefs.project_session)
{
/* save current (non-project) session (it could has been changed since program startup) */
@ -998,9 +1012,6 @@ static gboolean write_config(gboolean emit_signal)
if (p->description)
g_key_file_set_string(config, "project", "description", p->description);
g_key_file_set_boolean(config, "project", "make_in_base_path", p->make_in_base_path);
if (p->run_cmd)
g_key_file_set_string(config, "project", "run_cmd", p->run_cmd);
if (p->file_patterns)
g_key_file_set_string_list(config, "project", "file_patterns",
(const gchar**) p->file_patterns, g_strv_length(p->file_patterns));
@ -1008,7 +1019,7 @@ static gboolean write_config(gboolean emit_signal)
/* store the session files into the project too */
if (project_prefs.project_session)
configuration_save_session_files(config);
build_save_menu( config, (gpointer)p, GEANY_BCS_PROJ );
if (emit_signal)
{
g_signal_emit_by_name(geany_object, "project-save", config);
@ -1055,19 +1066,6 @@ gchar *project_get_base_path(void)
}
/* Returns: NULL if the default path should be used, or a UTF-8 path.
* Maybe in future this will support a separate project make path from base path. */
gchar *project_get_make_dir(void)
{
GeanyProject *project = app->project;
if (project && ! project->make_in_base_path)
return NULL;
else
return project_get_base_path();
}
/* This is to save project-related global settings, NOT project file settings. */
void project_save_prefs(GKeyFile *config)
{

View File

@ -35,14 +35,16 @@ typedef struct GeanyProject
gchar *description; /**< Short description of the project. */
gchar *file_name; /**< Where the project file is stored (in UTF-8). */
gchar *base_path; /**< Base path of the project directory (in UTF-8, maybe relative). */
gchar *run_cmd; /**< Project run command (in UTF-8). */
/** Identifier whether it is a pure Geany project or modified/extended
* by a plugin. */
gint type;
gchar **file_patterns; /**< Array of filename extension patterns. */
gboolean make_in_base_path;
struct GeanyProjectPrivate *priv; /* must be last, append fields before this item */
#ifdef GEANY_PRIVATE
/* Do not use following fields in plugins */
GPtrArray *build_filetypes_list; /* *< Project has custom filetype builds for these. */
#endif
}
GeanyProject;
@ -79,8 +81,6 @@ gboolean project_load_file_with_session(const gchar *locale_file_name);
gchar *project_get_base_path(void);
gchar *project_get_make_dir(void);
void project_save_prefs(GKeyFile *config);

View File

@ -218,14 +218,16 @@ end\n\
x = StdClass.new\n\
";
static const gchar templates_filetype_python[] = "#!/usr/bin/env python\n#\n\
static const gchar templates_filetype_python[] = "#!/usr/bin/env python\n\
# -*- coding: utf-8 -*-\n#\n\
{fileheader}\n\n\
\n\
def main():\n\
\n\
return 0\n\
\n\
if __name__ == '__main__': main()\n\
if __name__ == '__main__':\n\
main()\n\
";
static const gchar templates_filetype_latex[] = "\

View File

@ -1719,13 +1719,20 @@ void utils_tidy_path(gchar *filename)
const gchar *c, *needle;
gchar *tmp;
gssize pos;
gboolean preserve_double_backslash = FALSE;
g_return_if_fail(g_path_is_absolute(filename));
if (str->len >= 2 && strncmp(str->str, "\\\\", 2) == 0)
preserve_double_backslash = TRUE;
/* replace "/./" and "//" */
utils_string_replace_all(str, G_DIR_SEPARATOR_S "." G_DIR_SEPARATOR_S, G_DIR_SEPARATOR_S);
utils_string_replace_all(str, G_DIR_SEPARATOR_S G_DIR_SEPARATOR_S, G_DIR_SEPARATOR_S);
if (preserve_double_backslash)
g_string_prepend(str, "\\");
/* replace "/.." */
needle = G_DIR_SEPARATOR_S "..";
while (1)

View File

@ -644,8 +644,11 @@ gint win32_message_dialog_unsaved(const gchar *msg)
void win32_open_browser(const gchar *uri)
{
if (strncmp(uri, "file://", 7) == 0)
{
uri += 7;
while (*uri == '/')
uri++;
}
ShellExecute(NULL, "open", uri, NULL, NULL, SW_SHOWNORMAL);
}

View File

@ -76,8 +76,8 @@ static void installPHPRegex (const langType language)
"\\2", "i,interface,interfaces", NULL);
addTagRegex(language, "(^|[ \t])define[ \t]*\\([ \t]*['\"]?([" ALPHA "_][" ALNUM "_]*)",
"\\2", "d,macro,constant definitions", NULL);
addTagRegex(language, "(^|[ \t])function[ \t]+&?[ \t]*([" ALPHA "_][" ALNUM "_]*)",
"\\2", "f,function,functions", NULL);
addTagRegex(language, "^[ \t]*((public|protected|private|static)[ \t]+)*function[ \t]+&?[ \t]*([" ALPHA "_][" ALNUM "_]*)",
"\\3", "f,function,functions", NULL);
addTagRegex(language, "(^|[ \t])(\\$|::\\$|\\$this->)([" ALPHA "_][" ALNUM "_]*)[ \t]*=",
"\\3", "v,variable,variables", NULL);
addTagRegex(language, "(^|[ \t])(var|public|protected|private|static)[ \t]+\\$([" ALPHA "_][" ALNUM "_]*)[ \t]*[=;]",

View File

@ -166,7 +166,7 @@ static const char *skipEverything (const char *cp)
{
for (; *cp; cp++)
{
if (*cp == '"' || *cp == '\'')
if (*cp == '"' || *cp == '\'' || *cp == '#')
{
cp = skipString(cp);
if (!*cp) break;

View File

@ -314,7 +314,7 @@
/* #undef volatile */
/* Version number of package */
#define VERSION "0.18"
#define VERSION "0.19"
#define REVISION "-1"

53
wscript
View File

@ -35,17 +35,26 @@ Missing features: --enable-binreloc, make targets: dist, pdf (in doc/)
Known issues: Dependency handling is buggy, e.g. if src/document.h is
changed, depending source files are not rebuilt (maybe Waf bug).
The code of this file itself loosely follows PEP 8 with some exceptions
(line width 100 characters and some other minor things).
Requires WAF 1.5.7 and Python 2.4 (or later).
"""
import Build, Configure, Options, Utils
import sys, os, shutil, tempfile
import Build
import Configure
import Options
import Utils
import sys
import os
import shutil
import tempfile
from distutils import version
APPNAME = 'geany'
VERSION = '0.18'
VERSION = '0.19'
srcdir = '.'
blddir = '_build_'
@ -263,8 +272,11 @@ def configure(conf):
conf.env.append_value('CCFLAGS', '-g -DGEANY_DEBUG'.split())
conf.env.append_value('CCFLAGS', '-DHAVE_CONFIG_H')
# for now define GEANY_PRIVATE for all files, even though it should just be for src/*.
conf.env.append_value('CCFLAGS', '-DGEANY_PRIVATE')
# Scintilla flags
conf.env.append_value('CXXFLAGS', '-DNDEBUG -DGTK -DGTK2 -DSCI_LEXER -DG_THREADS_IMPL_NONE'.split())
conf.env.append_value('CXXFLAGS',
'-DNDEBUG -DGTK -DGTK2 -DSCI_LEXER -DG_THREADS_IMPL_NONE'.split())
def set_options(opt):
@ -277,9 +289,11 @@ def set_options(opt):
opt.add_option('--disable-plugins', action='store_true', default=False,
help='compile without plugin support [default: No]', dest='no_plugins')
opt.add_option('--disable-socket', action='store_true', default=False,
help='compile without support to detect a running instance [[default: No]', dest='no_socket')
help='compile without support to detect a running instance [[default: No]',
dest='no_socket')
opt.add_option('--disable-vte', action='store_true', default=target_is_win32(os.environ),
help='compile without support for an embedded virtual terminal [[default: No]', dest='no_vte')
help='compile without support for an embedded virtual terminal [[default: No]',
dest='no_vte')
opt.add_option('--enable-gnu-regex', action='store_true', default=False,
help='compile with included GNU regex library [default: No]', dest='gnu_regex')
# Paths
@ -292,6 +306,8 @@ def set_options(opt):
# Actions
opt.add_option('--htmldoc', action='store_true', default=False,
help='generate HTML documentation', dest='htmldoc')
opt.add_option('--hackingdoc', action='store_true', default=False,
help='generate HTML documentation from HACKING file', dest='hackingdoc')
opt.add_option('--apidoc', action='store_true', default=False,
help='generate API reference documentation', dest='apidoc')
opt.add_option('--update-po', action='store_true', default=False,
@ -456,7 +472,7 @@ def build(bld):
src/highlighting.h src/keybindings.h src/main.h src/msgwindow.h src/plugindata.h
src/plugins.h src/prefs.h src/project.h src/sciwrappers.h src/search.h src/support.h
src/templates.h src/toolbar.h src/ui_utils.h src/utils.h plugins/pluginmacros.h
plugins/geanyplugin.h plugins/geanyfunctions.h ''')
plugins/geanyplugin.h plugins/geanyfunctions.h src/build.h ''')
bld.install_files('${PREFIX}/include/geany/scintilla', '''
scintilla/include/SciLexer.h scintilla/include/Scintilla.h
scintilla/include/Scintilla.iface scintilla/include/ScintillaWidget.h ''')
@ -472,9 +488,9 @@ def build(bld):
html_dir = '' if is_win32 else 'html/'
html_name = 'Manual.html' if is_win32 else 'index.html'
for f in 'AUTHORS ChangeLog COPYING README NEWS THANKS TODO'.split():
bld.install_as("%s/%s%s" % (base_dir, ucFirst(f, is_win32), ext), f)
bld.install_as("%s/%s%s" % (base_dir, uc_first(f, is_win32), ext), f)
bld.install_files('${DOCDIR}/%simages' % html_dir, 'doc/images/*.png')
bld.install_as('${DOCDIR}/%s' % ucFirst('manual.txt', is_win32), 'doc/geany.txt')
bld.install_as('${DOCDIR}/%s' % uc_first('manual.txt', is_win32), 'doc/geany.txt')
bld.install_as('${DOCDIR}/%s%s' % (html_dir, html_name), 'doc/geany.html')
bld.install_as('${DOCDIR}/ScintillaLicense.txt', 'scintilla/License.txt')
if is_win32:
@ -498,7 +514,8 @@ def build(bld):
def shutdown():
is_win32 = False if not Build.bld else target_is_win32(Build.bld.env)
# the following code was taken from midori's WAF script, thanks
if not is_win32 and not Options.options.destdir and (Options.commands['install'] or Options.commands['uninstall']):
if not is_win32 and not Options.options.destdir and (Options.commands['install'] or \
Options.commands['uninstall']):
dir = Build.bld.get_install_path('${DATADIR}/icons/hicolor')
icon_cache_updated = False
try:
@ -522,15 +539,23 @@ def shutdown():
'doxygen could not be found. Please install the doxygen package.')
sys.exit(1)
if Options.options.htmldoc:
if Options.options.htmldoc or Options.options.hackingdoc:
# first try rst2html.py as it is the upstream default, fall back to rst2html
cmd = Configure.find_program_impl(Build.bld.env, 'rst2html.py')
if not cmd:
cmd = Configure.find_program_impl(Build.bld.env, 'rst2html')
if cmd:
if Options.options.hackingdoc:
file_in = '../HACKING'
file_out = 'hacking.html'
msg = 'HACKING HTML'
else:
file_in = 'geany.txt'
file_out = 'geany.html'
msg = 'HTML'
os.chdir('doc')
ret = launch(cmd + ' -stg --stylesheet=geany.css geany.txt geany.html',
'Generating HTML documentation')
ret = launch(cmd + ' -stg --stylesheet=geany.css %s %s' % (file_in, file_out),
'Generating %s documentation' % msg)
else:
Utils.pprint('RED',
'rst2html.py could not be found. Please install the Python docutils package.')
@ -579,7 +604,7 @@ def print_message(conf, msg, result, color = 'GREEN'):
conf.check_message_2(result, color)
def ucFirst(s, is_win32):
def uc_first(s, is_win32):
if is_win32:
return s.title()
return s