<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="generator" content="AsciiDoc 8.4.5" />
<title>Geany Build System Changes</title>
<style type="text/css">
/* Debug borders */
p, li, dt, dd, div, pre, h1, h2, h3, h4, h5, h6 {
/*
  border: 1px solid red;
*/
}

body {
  margin: 1em 5% 1em 5%;
}

a {
  color: blue;
  text-decoration: underline;
}
a:visited {
  color: fuchsia;
}

em {
  font-style: italic;
  color: navy;
}

strong {
  font-weight: bold;
  color: #083194;
}

tt {
  color: navy;
}

h1, h2, h3, h4, h5, h6 {
  color: #527bbd;
  font-family: sans-serif;
  margin-top: 1.2em;
  margin-bottom: 0.5em;
  line-height: 1.3;
}

h1, h2, h3 {
  border-bottom: 2px solid silver;
}
h2 {
  padding-top: 0.5em;
}
h3 {
  float: left;
}
h3 + * {
  clear: left;
}

div.sectionbody {
  font-family: serif;
  margin-left: 0;
}

hr {
  border: 1px solid silver;
}

p {
  margin-top: 0.5em;
  margin-bottom: 0.5em;
}

ul, ol, li > p {
  margin-top: 0;
}

pre {
  padding: 0;
  margin: 0;
}

span#author {
  color: #527bbd;
  font-family: sans-serif;
  font-weight: bold;
  font-size: 1.1em;
}
span#email {
}
span#revnumber, span#revdate, span#revremark {
  font-family: sans-serif;
}

div#footer {
  font-family: sans-serif;
  font-size: small;
  border-top: 2px solid silver;
  padding-top: 0.5em;
  margin-top: 4.0em;
}
div#footer-text {
  float: left;
  padding-bottom: 0.5em;
}
div#footer-badges {
  float: right;
  padding-bottom: 0.5em;
}

div#preamble {
  margin-top: 1.5em;
  margin-bottom: 1.5em;
}
div.tableblock, div.imageblock, div.exampleblock, div.verseblock,
div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
div.admonitionblock {
  margin-top: 1.5em;
  margin-bottom: 1.5em;
}
div.admonitionblock {
  margin-top: 2.5em;
  margin-bottom: 2.5em;
}

div.content { /* Block element content. */
  padding: 0;
}

/* Block element titles. */
div.title, caption.title {
  color: #527bbd;
  font-family: sans-serif;
  font-weight: bold;
  text-align: left;
  margin-top: 1.0em;
  margin-bottom: 0.5em;
}
div.title + * {
  margin-top: 0;
}

td div.title:first-child {
  margin-top: 0.0em;
}
div.content div.title:first-child {
  margin-top: 0.0em;
}
div.content + div.title {
  margin-top: 0.0em;
}

div.sidebarblock > div.content {
  background: #ffffee;
  border: 1px solid silver;
  padding: 0.5em;
}

div.listingblock > div.content {
  border: 1px solid silver;
  background: #f4f4f4;
  padding: 0.5em;
}

div.quoteblock {
  padding-left: 2.0em;
  margin-right: 10%;
}
div.quoteblock > div.attribution {
  padding-top: 0.5em;
  text-align: right;
}

div.verseblock {
  padding-left: 2.0em;
  margin-right: 10%;
}
div.verseblock > div.content {
  white-space: pre;
}
div.verseblock > div.attribution {
  padding-top: 0.75em;
  text-align: left;
}
/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
div.verseblock + div.attribution {
  text-align: left;
}

div.admonitionblock .icon {
  vertical-align: top;
  font-size: 1.1em;
  font-weight: bold;
  text-decoration: underline;
  color: #527bbd;
  padding-right: 0.5em;
}
div.admonitionblock td.content {
  padding-left: 0.5em;
  border-left: 2px solid silver;
}

div.exampleblock > div.content {
  border-left: 2px solid silver;
  padding: 0.5em;
}

div.imageblock div.content { padding-left: 0; }
span.image img { border-style: none; }
a.image:visited { color: white; }

dl {
  margin-top: 0.8em;
  margin-bottom: 0.8em;
}
dt {
  margin-top: 0.5em;
  margin-bottom: 0;
  font-style: normal;
  color: navy;
}
dd > *:first-child {
  margin-top: 0.1em;
}

ul, ol {
    list-style-position: outside;
}
ol.arabic {
  list-style-type: decimal;
}
ol.loweralpha {
  list-style-type: lower-alpha;
}
ol.upperalpha {
  list-style-type: upper-alpha;
}
ol.lowerroman {
  list-style-type: lower-roman;
}
ol.upperroman {
  list-style-type: upper-roman;
}

div.compact ul, div.compact ol,
div.compact p, div.compact p,
div.compact div, div.compact div {
  margin-top: 0.1em;
  margin-bottom: 0.1em;
}

div.tableblock > table {
  border: 3px solid #527bbd;
}
thead {
  font-family: sans-serif;
  font-weight: bold;
}
tfoot {
  font-weight: bold;
}
td > div.verse {
  white-space: pre;
}
p.table {
  margin-top: 0;
}
/* Because the table frame attribute is overriden by CSS in most browsers. */
div.tableblock > table[frame="void"] {
  border-style: none;
}
div.tableblock > table[frame="hsides"] {
  border-left-style: none;
  border-right-style: none;
}
div.tableblock > table[frame="vsides"] {
  border-top-style: none;
  border-bottom-style: none;
}


div.hdlist {
  margin-top: 0.8em;
  margin-bottom: 0.8em;
}
div.hdlist tr {
  padding-bottom: 15px;
}
dt.hdlist1.strong, td.hdlist1.strong {
  font-weight: bold;
}
td.hdlist1 {
  vertical-align: top;
  font-style: normal;
  padding-right: 0.8em;
  color: navy;
}
td.hdlist2 {
  vertical-align: top;
}
div.hdlist.compact tr {
  margin: 0;
  padding-bottom: 0;
}

.comment {
  background: yellow;
}

@media print {
  div#footer-badges { display: none; }
}

div#toctitle {
  color: #527bbd;
  font-family: sans-serif;
  font-size: 1.1em;
  font-weight: bold;
  margin-top: 1.0em;
  margin-bottom: 0.1em;
}

div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
  margin-top: 0;
  margin-bottom: 0;
}
div.toclevel2 {
  margin-left: 2em;
  font-size: 0.9em;
}
div.toclevel3 {
  margin-left: 4em;
  font-size: 0.9em;
}
div.toclevel4 {
  margin-left: 6em;
  font-size: 0.9em;
}
/* Workarounds for IE6's broken and incomplete CSS2. */

div.sidebar-content {
  background: #ffffee;
  border: 1px solid silver;
  padding: 0.5em;
}
div.sidebar-title, div.image-title {
  color: #527bbd;
  font-family: sans-serif;
  font-weight: bold;
  margin-top: 0.0em;
  margin-bottom: 0.5em;
}

div.listingblock div.content {
  border: 1px solid silver;
  background: #f4f4f4;
  padding: 0.5em;
}

div.quoteblock-attribution {
  padding-top: 0.5em;
  text-align: right;
}

div.verseblock-content {
  white-space: pre;
}
div.verseblock-attribution {
  padding-top: 0.75em;
  text-align: left;
}

div.exampleblock-content {
  border-left: 2px solid silver;
  padding-left: 0.5em;
}

/* IE6 sets dynamically generated links as visited. */
div#toc a:visited { color: blue; }
</style>
</head>
<body style="max-width:40em">
<div id="header">
<h1>Geany Build System Changes</h1>
<span id="author">Lex Trotman</span><br />
<span id="email"><tt><<a href="mailto:geany-devel@uvena.de">geany-devel@uvena.de</a>></tt></span><br />
<span id="revdate">January 2010</span>
</div>
<div id="preamble">
<div class="sectionbody">
<div class="paragraph"><p>This document describes the proposed changes to the Geany build system
specification and design.  This document describes changes from the last
released version of Geany (0.18), but also reflects the lessons learned
from a first implementation attempt.</p></div>
</div>
</div>
<h2 id="_purpose">Purpose</h2>
<div class="sectionbody">
<div class="paragraph"><p>The purpose of the changes is to improve the flexibility and
configurability of the actions performed by the Build menu.</p></div>
<div class="paragraph"><p>The main use cases which triggered the changes were:</p></div>
<div class="ulist"><ul>
<li>
<p>
support for running more genralised commands to support build tools
  other than make
</p>
</li>
<li>
<p>
ability to store customisations in project files to support projects
  using different tool sets
</p>
</li>
<li>
<p>
ability to set working directories for customised commands
</p>
</li>
<li>
<p>
GUI setup of all customisations
</p>
</li>
<li>
<p>
ability for plugins to affect the build process
</p>
</li>
</ul></div>
</div>
<h2 id="_requirements">Requirements</h2>
<div class="sectionbody">
<h3 id="_operations">Operations</h3><div style="clear:left"></div>
<div class="paragraph"><p>Since the terms action, event, command etc. have specific meanings the
term <strong>operation</strong> will be used in this document to describe what happens
when a Build menu item is activated.</p></div>
<div class="paragraph"><p>An operation has a configurable label with mnemonic, to be shown on
the Build menu.  The label must allow for translations to be provided
and an optional icon to be shown on the build menu and the toolbar.</p></div>
<div class="paragraph"><p>Other than this icon there is no interface between operations and
the toolbar, as the toolbar should work by activating the
appropriate Build menu item and so does not need an interface to
the operations.</p></div>
<div class="paragraph"><p>The Build menu must be able to trigger operations which are:</p></div>
<div class="ulist"><ul>
<li>
<p>
internal to the Geany or plugin code, initially:
</p>
<div class="ulist"><ul>
<li>
<p>
next error
</p>
</li>
<li>
<p>
previous error
</p>
</li>
<li>
<p>
show configuration dialog
</p>
</li>
</ul></div>
</li>
<li>
<p>
programs to be executed external to Geany.
</p>
</li>
</ul></div>
<div class="paragraph"><p>External operations must be able to configure the following attributes:</p></div>
<div class="ulist"><ul>
<li>
<p>
the command to be executed in a shell - a working directory where
  the command is to be executed - how the command output is handled:
</p>
<div class="ulist"><ul>
<li>
<p>
output parsed by Geany to the Build message tab (re-named
    Compiler tab) and a regex must be configurable for that parsing (or
    fallback to coded parsing ?still needed?)
</p>
</li>
<li>
<p>
output to a terminal (VTE or the configured terminal)
</p>
</li>
<li>
<p>
output to Geany’s terminal (or lost if Geany is started fron a
    Gnome/KDE/Xfce etc menu)
</p>
</li>
</ul></div>
</li>
<li>
<p>
a menu label if the command is stopable, the menu item will change to
  this label while the command is running and the icon will change to
  the standard stop icon.  Activating the menu item again will attempt
  to stop the running command.
</p>
</li>
<li>
<p>
a sensitivity group, only one operation of a sensitivity group can
  run at any time, all menu items with operations in the same group are
  set insensitive while a command in the group is running.  The menu
  item which triggered the operation will also be insensitive if the
  command is not stopable.
</p>
</li>
</ul></div>
<div class="paragraph"><p>All commands whose output is to be parsed will automatically be in
one sensitivity group so that only one parser stream is required at
any one time.</p></div>
<div class="paragraph"><p>The command and working directory fields will accept the following
substitutions:</p></div>
<div class="ulist"><ul>
<li>
<p>
%c{…} - the text returned from a dialog box
</p>
</li>
<li>
<p>
%d - the full path of the directory of the current document
</p>
</li>
<li>
<p>
%e - the filename of the current document without extension
</p>
</li>
<li>
<p>
%f - the filename of the current document
</p>
</li>
<li>
<p>
%p - the project base path as configured in the open project
</p>
</li>
<li>
<p>
%s - the current file separator (i.e. %d%s%f = full path to the
  current document)
</p>
</li>
</ul></div>
<div class="paragraph"><p>The substitutions %d, %e, %f will substitute nothing if there is no
current named document.  The substitution %p will substitute
nothing if no project is open.</p></div>
<div class="paragraph"><p>The dialog box generated by %c will have the menu label as the
title, it will contain a text entry with the text inside the {}
displayed above the entry.  The dialog will have an Ok button which
causes the text in the entry to replace the %c{..} and a Cancel
button which will replace the %c{…} with nothing.  The dialog
will default to the last entry and remember previous entries.  A missing
{} will display no text.</p></div>
<h3 id="_configuration_sources">Configuration Sources</h3><div style="clear:left"></div>
<div class="paragraph"><p>The configuration of operations must come from multiple sources:</p></div>
<div class="ulist"><ul>
<li>
<p>
defaults
</p>
</li>
<li>
<p>
system configuration files (installed with Geany)
</p>
</li>
<li>
<p>
user configuration files
</p>
</li>
<li>
<p>
the Geany program or plugins
</p>
</li>
</ul></div>
<div class="paragraph"><p>Each source must be able to provide configuration for a specific
filetype and for all filetypes not specifically configured.</p></div>
<div class="paragraph"><p>When more than one source has an operation configured for the same
build menu item the one that will be used is chosen using a simple
fixed priority order, from first choice to last:</p></div>
<div class="ulist"><ul>
<li>
<p>
configuration by Geany or a plugin for the filetype of the current
  document
</p>
</li>
<li>
<p>
configuration by Geany or a plugin for any filetype
</p>
</li>
<li>
<p>
user configuration for the filetype of the current document
</p>
</li>
<li>
<p>
user configuration for any filetype
</p>
</li>
<li>
<p>
system configuration for the filetype of the current document
</p>
</li>
<li>
<p>
system configuration for any filetype
</p>
</li>
<li>
<p>
default values
</p>
</li>
</ul></div>
<div class="paragraph"><p>The first source with a configuration present will provide all
values, if a value is not set for an attribute in a configuration
then a blank string, off or the first of a list will be used as
appropraite to the type of attribute..</p></div>
<h3 id="_menu_layout">Menu Layout</h3><div style="clear:left"></div>
<div class="paragraph"><p>The build menu must be able to be organised in to several groups of
items with separators between them.  Grouping similar operations
provides a better user experience in a menu which has the potential
to contain widely differing operations.  The number of groups and
the number of operations in them must be configurable but a maximum
must be set at startup.  The default and minimum will be 5 sections
sized from the top of the menu 3, 4, 2, 2, 1.</p></div>
<div class="paragraph"><p>The default menu layout is:</p></div>
<div class="ulist"><ul>
<li>
<p>
current file related operations section, language dependent e.g. for
  the C language:
</p>
<div class="ulist"><ul>
<li>
<p>
Compile current file
</p>
</li>
<li>
<p>
Link current file
</p>
</li>
</ul></div>
</li>
<li>
<p>
multi file related operations section, language independent:
</p>
<div class="ulist"><ul>
<li>
<p>
Make
</p>
</li>
<li>
<p>
Make Custom Target
</p>
</li>
<li>
<p>
Make Object
</p>
</li>
</ul></div>
</li>
<li>
<p>
error navigation operations section:
</p>
<div class="ulist"><ul>
<li>
<p>
Next error
</p>
</li>
<li>
<p>
Previous error
</p>
</li>
</ul></div>
</li>
<li>
<p>
execution related operations section, language independent:
</p>
<div class="ulist"><ul>
<li>
<p>
Execute current file
</p>
</li>
</ul></div>
</li>
<li>
<p>
Configuration operations section:
</p>
<div class="ulist"><ul>
<li>
<p>
Show configuration dialog
</p>
</li>
</ul></div>
</li>
</ul></div>
<h3 id="_configuration">Configuration</h3><div style="clear:left"></div>
<div class="paragraph"><p>Other than the number of sections and their sizes, all configuration
shall be available from the GUI.</p></div>
<div class="paragraph"><p>Only one dialog shall be used for the whole menu.  The dialog shall
indicate the form that the menu will take after the changes are applied.</p></div>
<div class="paragraph"><p>The dialog shall have more than one level of detail so that it will
not be overwhelming on first use.</p></div>
<div class="paragraph"><p>The dialog must be able to edit the configuration for user and
project sources for both the filetype of the current document and
the filetype independent settings.  To prevent the filetype changing the
dialog may be modal.</p></div>
<div class="paragraph"><p>At full detail the dialog must be able to show other configuration
sources that may influence the operation that a menu item will
perform (eg system or default), however these cannot be changed by
the dialog.</p></div>
</div>
<h2 id="_design">Design</h2>
<div class="sectionbody">
<div class="paragraph"><p>Process id per is per sensitivity group</p></div>
<div class="paragraph"><p>Sensitivity flag for internals to set, gives feedback to update_menu
when Geany/plugins want some special sensitivity behaviour.</p></div>
<div class="paragraph"><p>Each menu item with a %c has a separate dialog memory.</p></div>
<div class="paragraph"><p>Operation structure should be opaque with getter/setter.  The setter
should trigger gui update if needed and therefore should be
multi-field. Updating all fields that are to change at once allows
consistency checking.  Updating one field at a time may result in
inconsistent states between field updates, (ie update one field
creates an inconsistent state until another field is updated to
match) so it is difficult to know when it is safe to to check
consistency and when it is safe to update the GUI. Also reduces
number of potential GUI updates.</p></div>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2010-01-26 16:18:24 EST
</div>
</div>
</body>
</html>