PhpStorm: possible to update file template on each file edit? - templates

My PhpStorm 2017.2 project requires that each new file be created from a specific. In "Settings >> Editor >> File and Code Templates >> PHP File", I have the following template:
<?php
/**
* #author John Doe
* #copyright ${YEAR} Acme
* #created ${DATE}
* #modified ${DATE}
*/
This works well. PhpStorm fills in the year and date dynamically. However, when I later come back and make changes to the file, I always need to remember to change the #modified line manually. Is there a way to automate this so that onSave or onCommit (for version controlled file), the line is updated with the current value of ${DATE}?

Not possible ATM.
https://youtrack.jetbrains.com/issue/IDEABKL-7178 -- watch this ticket (star/vote/comment) to get notified on any progress. Right now there are no plans to implement something like that in nearest future.
On another hand (as mentioned in the comment in aforementioned ticket) -- see if standard "Copyright" plugin will be of any help (never used it myself so no idea of what exactly it can do).
One possible solution involves writing your own script/program (PHP or whatever other language you can use) that will parse your file (regex matching should do fine here -- no real need into going and parsing file into tokens) and update such info:
look at each line until the matching line will be found (some guard logic can be added to limit the number of lines to be parsed: if no matching line is found in first xx (e.g. 20) lines then assume that this file has no such comment/line);
update date/time part based on file modification timestamp.
Once you have such script -- just use File Watcher functionality so it gets called on each file modification.
Possible downside: File Watcher gets triggered when file modification is detected ... which may include changes made outside (e.g. another editor/download from remote host/another VCS branch/etc)). This may lead to unnecessary/unwanted updates.
If File Watcher functionality is not suitable for whatever reason -- look into grunt -watch or alike where you may easily disable watching (so your script will only be called when your watcher (build runner) is watching).

Related

adding a custom plugin to google-fluentd

I need to capture file descriptors for a given process. This is simular to what collectd's processes plugin does, but need to get this on the fluentd, google-fluentd specifically rails.
I've added my plugin under /etc/google-fluentd/plugin directory and no luck, it is not getting registered. I've even moved under /opt/google-fluentd/embedded/lib/ruby/gems/2.6.0/gems/fluentd-1.7.4/lib/fluent/plugin still no luck. Out of desperation I have also tried renaming in_tail.rb to in_tail2.rb and tail plugin is gone.
2020-08-14 18:28:16 -0700 [error]: fluent/log.rb:362:error: config error file="/etc/google-fluentd/google-fluentd.conf" error_class=Fluent::ConfigError error="Unknown input plugin 'tail'. Run 'gem search -rd fluent-plugin' to find plugins"
Which tells me that there is some other place where plugin must be mentioned. Is it too naive to think that I can just write a single file plugin under /etc/google-fluentd/plugin?
After a few hours of going up and down the call stack in the fluentd trying to figure out the logic behind why and which plugins fluentd loads here is what I figured out.
#type has to match registration call and filename!
ie i had used
#type fc_count
my filename was
/etc/google-fluentd/in_fd.rb
with
Fluent::Plugin.register_input('fd_count', self)
Although type and registration matched, fluent couldn't match file path to plugin/in_fd.rb as it loads configuration. Basically if you don't use a plugin it won't load it and the way it determines it is by going through config. This is the reason why when I renamed an existing input plugin it was no longer found.

MS Word 2010 Completely reformatted my whole document

I'm thinking this might have something to do with a template, but it's really weird.
I started off with a .doc file and a .docx file that I had previously edited, combined them, and saved the result as a .docx file. Both files were originally created as templates by someone else long ago. Within a few minutes, the fonts and spacing of everything in the document have been changed, making a total mess out of my document. I also noticed something in the lower left corner referencing "contacting" a template. I never noticed this before with these templates.
What a mess. How can I make it stop doing this? If I take the time to reformat everything the way I want it again, I don't want it to revert back the next time my back is turned.
Thanks,
Rebeccah
Ah. I got it figured out. One of the component documents, and the merged document, had a template attached to it that was stored on a server. The template file on the server doesn't exist any more - someone must have recently deleted it. The reformatting apparently reflects Word automatically changing the template to normal.dot.
If I catch it in time, before the changes are made, I can save the file as a .dot or .dotx (template) file, and then attach that local template file to future documents so they don't have to rely on the template that is no longer on the server.
How I figured this out:
Google found an answer to a question about disabling a long wait for a linked file that no longer existed, leading me to File | Options | Advanced | General - uncheck "Update automatic links at open." That didn't undo the reformatting that had already happened, but may have prevented reformatting of the component document the next time I opened it.
The same answer pointed me to the right side of the File page, where various file properties are displayed. When I click on "Show All Properties", I can see the file name of the Template file, as the eighth property displayed.
General googling about Word templates led me to File | Options | Customize Ribbon | Customize the Ribbon, where I checked the previously empty box next to "Developer". Now, Developer | Document Template allows me to see and change the location of the document template.
I opened a previous version of one of the component files (the .doc file), the one that had the template from the server attached to it, and watched Word search for the template. But it did not reformat it the file. I saved the file as .dot, as .dotx with compatibility, and as .dotx - just to be sure I had all necessary options available.
I opened my reformatted composite file, went to Developer | Document Template, and specified my recently saved .dotx file as the template, made sure that "Automatically update document styles" was checked, and clicked OK.
Voila! I have my previous formatting back.
Rebeccah

Complex WinMerge filters

I've just started a project involving a customized OTRS 3.1.
In this project we have two folders, the original kernel folder, and the custom kernel folder.
If a file is present on the custom kernel folder, then it overrides the original kernel folder file. Thus, updating the version of OTRS 3.1 to the most stable one, is just a matter of substituting the original kernel folder. But We have a problem: if a customized file is updated, the update is ignored, since our customization overrides the original one. So we need to detect those conflicts in order to apply the enhancements to our customized file manually.
So to achieve it I planned the next strategy. Let's assume I have the next file at the original kernel file:
print "Hello ";
print "World\n";
I want to customize it, changing World by "ACME", So I copy this file to the custom folder and change it to:
print "Hello ";
##- CUSTOM CODE
##- Date: 10/02/2014
##- By: Dave
##- Original code:
=pod
print "World\n";
=cut
##< Start custom code
print "ACME\n";
## end custom code >##
=pod and =cut are a block comment
Now let's imagine that to print the word Hello is detected as a risk, and they change the code of the file on a new stable version to:
print "Hi ";
print "World\n";
When applying the change to my original folder, I will not take profit of the security fix, since I have a custom file that still contains the Hello word. That said, I want to use WinMerge (or other tool that can achieve the same result) to detect my custom code tags so:
The lines starting by ##- are ignored.
The lines =pod and =cut are ignored.
The blocks between ##< and >## are ignored
Thus the first original file and my custom file will be identical after filtered, but after the update, it will detect the difference and allow me to merge the changes to my custom version.
I know how to create the filter for the lines starting by ##- or equal to =pod or =cut. But I don't know how to ignore a multiline block from the comparison.
Do you know how can I achieve what I want? If not with WinMerge, Is there any another tool that can help me automating this task?
Thank you very much in advance!

How to override the default text in MATLAB

In MATLAB, when you click File -> New -> Function M-File, you get a file with the following contents:
function [ output_args ] = Untitled( input_args )
%UNTITLED Summary of this function goes here
% Detailed explanation goes here
end
Is it possible to override this behaviour, and specify your own text?
(The motivation is that I'm trying to persuade my colleagues to document their m-files more thoroughly, and having default text for them to fill in might encourage them.)
I didn't even know File->New->Function did that.
The way I solved the issue was to write a function that you call via
>>newFunction myNewFunctionName
It then
pops up an inputdlg window, which asks the user for the synopsis and the H1 line and allows to already write help to explain input and output arguments. There, the user also selects whether myNewFunctionName is a function or a class in order to choose the right header and 'function call'
checks whether a function of the same name exists already
asks for a folder to save the function, and
opens the function in the editor
The header is set up so that it's easy to fill in info about input and output. It also automatically lists the username of the person who created the file as well as the date and the Matlab version.
EDIT
For new classes, the template function automatically makes sure that they subclass my general superclass that implements methods such as 'help' (which calls doc(class(obj)) )
Now if the template functionwould also write the algorithm part of the function, it would be really convenient. :)
EDIT2
Here's a link to the function on the file exchange.
I would suggest making your own default m-file template, called default.m for example, and placing it in a folder on the MATLAB path where your colleagues can access it. You should then set the file to be read-only. Your colleagues can then execute any one of the following commands in the MATLAB Command Window when they want to create a new function m-file:
open default.m
open('default.m')
edit default.m
edit('default.m')
The functions OPEN and EDIT will open a file in the MATLAB Editor. Since the file default.m is read-only, if anyone tries to save over it they will get a dialog box warning them as such and asking them to save to a new file (or overwrite it). That should keep them from accidentally modifying the template.
I searched through all text files starting from matlabroot folder, but could not find that template. Seems it's hard-coded, which is weird.
I like Jonas approach. As my two cents, you can download a function (not mine) doing similar things with some customization from here.
After more pondering, I've come up with a solution that I'm happy with, combining Jonas' and gnovice's answers. It's a function that creates a new m-file (with template documentation), and opens it in the editor. It is available from the Matlab Central File Exchange.

Best Tips for documenting code using doxygen? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Closed 7 years ago.
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
My team is starting to document our C code using doxygen, paying particular attention to our public API headers. There appears to be a lot of flexibility and different special commands in doxygen, which is great, but it's not clear what's a good thing and what's a bad thing without trial and error.
What are your favourite ways to mark up your code, what are your MUST DOs and DO NOTs?
Please provide your top tips, one per answer to facilitate voting.
I am looking to define our whole approach to API documentation, including providing a template to get the rest of the team started. So far I have something like this:
/**
* #file example_action.h
* #Author Me (me#example.com)
* #date September, 2008
* #brief Brief description of file.
*
* Detailed description of file.
*/
/**
* #name Example API Actions
* #brief Example actions available.
* #ingroup example
*
* This API provides certain actions as an example.
*
* #param [in] repeat Number of times to do nothing.
*
* #retval TRUE Successfully did nothing.
* #retval FALSE Oops, did something.
*
* Example Usage:
* #code
* example_nada(3); // Do nothing 3 times.
* #endcode
*/
boolean example(int repeat);
You don't need and should not write the name of the file in the #file directive, doxygen reads the name of the file automatically. The problem with writing the name of the file is that when you rename the file you will have to change the #file directive as well.
Providing #author and #date information is also useless most of the time since the source control system does it a lot better than someone editing the files manually.
You also don't have to write #brief if you use the following Doxygen syntax and enable JAVADOC_AUTOBRIEF in doxygen's configuration:
/*! Short Description on the first line
Detailed description...
...
*/
void foo(void) {}
The #name directive for functions is also 100% redundant most of the time and completely useless. It only brings errors when someone modifies the name of the function and not the doxygen #name.
Write a descriptive home page using #mainpage (in a separate header file just for this purpose). Consider, as shown in my example, making it a guide to your main classes/functions and modules.
Another Sample
Whilst I was getting the above-linked main oofile doxygen content back online, here's an example from some current client work using Markdown format. Using Markdown you can refer to a mainpage in markdown (in the Doxygen settings) which is great for the typical readme.md file included in open-source projects.
Lingopal
========
Developer Documentation started when Andy Dent took over support in May 2014.
There are a number of pages in Markdown format which explain key aspects:
- #ref doc/LingopalBuilding.md
- #ref doc/LingopalSigning.md
- #ref doc/LingopalDatabases.md
- #ref doc/LingopalExternals.md
See the Related Pages list for more.
-------------
_Note_
These pages, whilst readable by themselves, are designed to be run through the [Doxygen](http://www.doxygen.com) code documentation engine which builds an entire local cross-referenced set of docs. It uses a minor [extension of Markdown formatting.](http://www.stack.nl/~dimitri/doxygen/manual/markdown.html)
The settings to generate the documentation are `Lingopal.doxy` and `LingopalDocOnly.doxy`. The latter is used for quick re-generation of just these additional pages.
Use Groups to organise your code into modules.
Remember that you can put almost everything into multiple groups so they can be used to provide semantic tagging like the tags in Stack Overflow. For example, you might tag things as specific to a given platform.
You can also use groups to match a folder hierarchy within an IDE, as shown in my RB2Doxy sample output.
Groups work well when nested - I have a large example for the OOFILE source.
Some commands i use in my code :
\todo { paragraph describing what is to be done } Useful to keep track of todos, a page will be created in final documentation containing your todo list.
\c <word> Displays the argument using a typewriter font. Use this to refer to a word of code. I would use it before "TRUE" and "FALSE" in your example.
\a , \warning , \see : see http://www.stack.nl/~dimitri/doxygen/commands.html#cmdc for description
A good "best practice" (though not always achievable) is to provide short, working examples for every API, and pull them into the help using \includelineno (or \include for no line numbers). These can be unit tests, if they're written so users can understand them (ie, not hooked into a larger test harness). As a nice side effect, changes to the API will break the samples, so they have to be kept up to date.
You can describe an API in words, but there's nothing like seeing the actual code to understand how to use it.
As I find myself editing code on higher-resolution screens I've moved from using the backslash to the # prefix on Doxygen commands. Not so noisy backslash has found itself now too damned hard to make out the Doxygen commands.
If you are sure your team will follow such a heavyweight template, fine, use it as shown.
Otherwise, it looks like JavaDoc. One of the nice things about Doxygen is how good a job it does without having to use use such strong markup. You don't need to use #name and with the JAVADOC_AUTOBRIEF setting you can skip #brief - just make sure the first line of the comment is a reasonable brief description.
I prefer descriptive names over enforcing documentation and encouraging people to add comments only when they add significant value. That way, the valuable comments aren't drowned out by all the noise.
If you have bugs located in the code or you find bugs you can also tag in the code like this:
/** #bug The text explaining the bug */
When you then run doxygen you get a seperate Bug List alongside lists like Todo List
If you have a really, really big project -- big enough that Doxygen runs take over an hour -- you can cut it up into multiple modules that Doxygen later links together using tag files.
For example, if you have a big MSVC solution with twenty projects in it, you can make directory be its own Doxygen run, and then use tag-files to glue together the output the same way a linker glues together .libs to make an executable.
You can even take the linking metaphor more literally and make each Doxy config file correspond to a .vcproj file, so that each project (eg .lib or .dll) gets its own Doxy output.
I use a subversion post-commit hook to pull out the directories that have changed, write them to a file and then every night I automatically re-generate the doxygen html on our webserver so we always have up-to-date docco.
Every project I want documented has a little project.doxy file that contains the per-project settings and an include to the main doxygen settings - eg:
PROJECT_NAME = "AlertServer"
PROJECT_NUMBER = 8.1.2
INPUT = "C:/Dev/src/8.1.2/Common/AlertServer"
HTML_OUTPUT = "AlertServer"
#INCLUDE = "c:\dev\CommonConfig.doxy"
For Windows SVN server, use the hook:
#echo off
for /F "eol=¬ delims=¬" %%A in ('svnlook dirs-changed %1 -r %2') do echo %%A >> c:\svn_exports\export.txt
and then run this nightly:
#echo off
rem ---------------
rem remove duplicates.
type nul> %TEMP%.\TEMP.txt
for /F "eol=¬ delims=¬" %%a in (c:\svn_exports\export.txt) do (
findstr /L /C:"%%a" < %TEMP%.\TEMP.txt > nul
if errorlevel=1 echo %%a>> %TEMP%.\TEMP.txt
)
copy /y %TEMP%.\TEMP.txt export_uniq.cmd >nul
if exist %TEMP%.\TEMP.txt del %TEMP%.\TEMP.txt
rem ---------------
rem fetch all the recently changed directories into the svn_exports directory
for /F "eol=¬ delims=¬" %%A in (c:\svn_exports\export_uniq.cmd) do (
svn export "file:///d:/repos/MyRepo/%%A" "c:/svn_exports/%%A" --force
)
rem ---------------
rem search through all dirs for any config files, if found run doxygen
for /R c:\svn_exports %%i in (*.doxy) do c:\tools\doxygen\bin\doxygen.exe "%i"
rem ---------------
rem now remove the directories to be generated.
del /F c:\svn_exports
this removes duplicate entries, finds all projects that have a .doxy project file, and runs doxygen on them. Voila: fully documented, always up-to-date code on a webserver.
For complex projects it may be useful to have a separate file for module management, which controls the groups and subgroups. The whole hierarchy can be in one place and then each file can simply stuff to the child groups. e.g.:
/**
* #defgroup example Top Level Example Group
* #brief The Example module.
*
* #{
*/
/**
* #defgroup example_child1 First Child of Example
* #brief 1st of 2 example children.
*/
/**
* #defgroup example_child2 Second Child of Example
* #brief 2nd of 2 example children.
*/
// #}
Simply including the definition of a group within the { } of another group makes it a child of that group. Then in the code and header files functions can just be tagged as part of whatever group they are in and it all just works in the finished documentation. It makes refactoring the documentation to match the refactor code much easier.
Uses lots and lots of links. This can be done using see also links (\see or #see if you prefer), and making sure that you use any references to other class names in documentation by their correct class name. For example if you refer to class FUZZYObject as an "object", then write immediately after it the name of the class (e.g. "frazzle the objects (FUZZYObject)").
Automatically build and publish your documentation. As part of automatically building the documentation, pay attention to the warnings, its very easy to write badly structure doxygen comments.
Use \example as much as you can. It auto-links API elements to example code.
Don't bother with #author or #date (#date was mentioned in another post). These are both handled by a revision control system.
Always include a description with your classes. Try to say how a class is used, or why it is used, not just what it is (which usually just reflects the name anyway).
Group your member functions and fields if it makes sense to do so with \defgroup. This is very helpful, even if you don't say much.
If you are worried that some team members will avoid documenting or you just want a working minimal sets of documentation, you can enable these in your doxygen configuration.
WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
As part of your doxygen build process save the warnings to a file and try to get and keep the warning count as low as possible (0 if that is reasonable). If you do this, every public and protected class member will need at least an #brief, #param for each function argument and an #return. This is good enough to describe most APIs and not too much to encumber other living codebases.
You should, of course, encourage people to document as much as they feel is required on a case by case basis, as long as they meet the minimum project standards. Don't set the minimum too high though, then you may not get useful documentation in the end.
For example, in our project, everything another coder is likely to touch should be documented. Enabling the warnings let see how close that goal we are. We also try to use #internal to describe what/why we do what we do with some of our private members.
If you find that the configuration directive INLINE_SOURCES puts too much code in the documentation, you can manually quote specific portions of the code using the \snippet command.
/**
* Requirment XYZ is implemented by the following code.
*
* \snippet file.c CODE_LABEL
*/
int D()
{
//[CODE_LABEL]
if( A )
{
B= C();
}
//[CODE_LABEL]
}
note: snippet gets its files from the EXAMPLE_PATH, not where the source path is. You will have to put the same list of files and paths from INPUT directive on the EXAMPLE_PATH directive.
For larger projects taking 5+min to generate, I found it useful to quicly be able to generate doxygen for a single file and view it in a web browser.
While references to anything outside the file won't resolve, it can still useful to see the basic formatting is ok.
This script takes a single file and the projects doxy config and runs doxygen, I've set this up to run from my IDE.
#!/usr/bin/env python3
"""
This script takes 2-3 args: [--browse] <Doxyfile> <sourcefile>
--browse will open the resulting docs in a web browser.
"""
import sys
import os
import subprocess
import tempfile
doxyfile, sourcefile = sys.argv[-2:]
tempfile = tempfile.NamedTemporaryFile(mode='w+b')
doxyfile_tmp = tempfile.name
tempfile.write(open(doxyfile, "r+b").read())
tempfile.write(b'\n\n')
tempfile.write(b'INPUT=' + os.fsencode(sourcefile) + b'\n')
tempfile.flush()
subprocess.call(("doxygen", doxyfile_tmp))
del tempfile
# Maybe handy, but also annoying as default.
if "--browse" in sys.argv:
import webbrowser
webbrowser.open("html/files.html")