mirror of https://gitlab.com/basile.b/dexed.git
add an editor command to insert ddoc templates, close #135
This commit is contained in:
parent
260323080f
commit
6be3267993
|
@ -42,6 +42,7 @@ object CurrentProject: TCENativeProject
|
|||
'src/mainfun.d'
|
||||
'src/common.d'
|
||||
'src/halstead.d'
|
||||
'src/ddoc_template.d'
|
||||
)
|
||||
ConfigurationIndex = 1
|
||||
end
|
||||
|
|
|
@ -0,0 +1,193 @@
|
|||
module ddoc_template;
|
||||
|
||||
import
|
||||
std.stdio;
|
||||
import
|
||||
iz.memory;
|
||||
import
|
||||
dparse.ast, dparse.lexer, dparse.parser, dparse.rollback_allocator;
|
||||
|
||||
/**
|
||||
* Finds the declaration at caretLine and write its ddoc template
|
||||
* in the standard output.
|
||||
*/
|
||||
void getDdocTemplate(const(Module) mod, int caretLine)
|
||||
{
|
||||
DDocTemplateGenerator dtg = construct!DDocTemplateGenerator(caretLine);
|
||||
dtg.visit(mod);
|
||||
}
|
||||
|
||||
final class DDocTemplateGenerator: ASTVisitor
|
||||
{
|
||||
alias visit = ASTVisitor.visit;
|
||||
|
||||
private:
|
||||
|
||||
int _caretline;
|
||||
|
||||
public:
|
||||
|
||||
this(int caretline)
|
||||
{
|
||||
_caretline = caretline;
|
||||
}
|
||||
|
||||
override void visit(const(FunctionDeclaration) decl)
|
||||
{
|
||||
if (decl.name.line == _caretline)
|
||||
{
|
||||
writeln("/**\n * <short description> \n * \n * <detailed description>\n *");
|
||||
|
||||
if (decl.templateParameters || decl.parameters)
|
||||
{
|
||||
writeln(" * Params:");
|
||||
|
||||
if (decl.templateParameters && decl.templateParameters.templateParameterList)
|
||||
{
|
||||
foreach(const TemplateParameter p; decl.templateParameters
|
||||
.templateParameterList.items)
|
||||
{
|
||||
if (p.templateAliasParameter)
|
||||
writeln(" * ", p.templateAliasParameter.identifier.text, " = <description>");
|
||||
else if (p.templateTupleParameter)
|
||||
writeln(" * ", p.templateTupleParameter.identifier.text, " = <description>");
|
||||
else if (p.templateTypeParameter)
|
||||
writeln(" * ", p.templateTypeParameter.identifier.text, " = <description>");
|
||||
else if (p.templateValueParameter)
|
||||
writeln(" * ", p.templateValueParameter.identifier.text, " = <description>");
|
||||
}
|
||||
}
|
||||
if (decl.parameters)
|
||||
{
|
||||
foreach(i, const Parameter p; decl.parameters.parameters)
|
||||
{
|
||||
if (p.name.text != "")
|
||||
writeln(" * ", p.name.text, " = <description>");
|
||||
else
|
||||
writeln(" * __param", i, " = <description>");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (decl.returnType)
|
||||
{
|
||||
if (decl.returnType.type2 && decl.returnType.type2
|
||||
&& decl.returnType.type2.builtinType != tok!"void")
|
||||
writeln(" * \n * Returns: <return description>");
|
||||
}
|
||||
|
||||
writeln(" */");
|
||||
|
||||
}
|
||||
else if (decl.name.line > _caretline)
|
||||
return;
|
||||
decl.accept(this);
|
||||
}
|
||||
|
||||
override void visit(const(TemplateDeclaration) decl)
|
||||
{
|
||||
visitTemplateOrAggregate(decl);
|
||||
}
|
||||
|
||||
override void visit(const(ClassDeclaration) decl)
|
||||
{
|
||||
visitTemplateOrAggregate(decl);
|
||||
}
|
||||
|
||||
override void visit(const(StructDeclaration) decl)
|
||||
{
|
||||
visitTemplateOrAggregate(decl);
|
||||
}
|
||||
|
||||
override void visit(const(UnionDeclaration) decl)
|
||||
{
|
||||
visitTemplateOrAggregate(decl);
|
||||
}
|
||||
|
||||
private void visitTemplateOrAggregate(T)(const(T) decl)
|
||||
{
|
||||
if (decl.name.line == _caretline)
|
||||
{
|
||||
writeln("/**\n * <short description> \n * \n * <detailed description>\n *");
|
||||
|
||||
if (decl.templateParameters)
|
||||
{
|
||||
writeln(" * Params:");
|
||||
|
||||
if (decl.templateParameters && decl.templateParameters.templateParameterList)
|
||||
{
|
||||
foreach(const TemplateParameter p; decl.templateParameters
|
||||
.templateParameterList.items)
|
||||
{
|
||||
if (p.templateAliasParameter)
|
||||
writeln(" * ", p.templateAliasParameter.identifier.text, " = <description>");
|
||||
else if (p.templateTupleParameter)
|
||||
writeln(" * ", p.templateTupleParameter.identifier.text, " = <description>");
|
||||
else if (p.templateTypeParameter)
|
||||
writeln(" * ", p.templateTypeParameter.identifier.text, " = <description>");
|
||||
else if (p.templateValueParameter)
|
||||
writeln(" * ", p.templateValueParameter.identifier.text, " = <description>");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
writeln(" */");
|
||||
|
||||
}
|
||||
else if (decl.name.line > _caretline)
|
||||
return;
|
||||
decl.accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
version(unittest)
|
||||
{
|
||||
DDocTemplateGenerator parseAndVisit(const(char)[] source, int caretLine)
|
||||
{
|
||||
writeln;
|
||||
RollbackAllocator allocator;
|
||||
LexerConfig config = LexerConfig("", StringBehavior.source, WhitespaceBehavior.skip);
|
||||
StringCache cache = StringCache(StringCache.defaultBucketCount);
|
||||
const(Token)[] tokens = getTokensForParser(cast(ubyte[]) source, config, &cache);
|
||||
Module mod = parseModule(tokens, "", &allocator);
|
||||
DDocTemplateGenerator result = construct!(DDocTemplateGenerator)(caretLine);
|
||||
result.visit(mod);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
unittest
|
||||
{
|
||||
q{ module a;
|
||||
void foo(A...)(A a){}
|
||||
}.parseAndVisit(2);
|
||||
}
|
||||
|
||||
unittest
|
||||
{
|
||||
q{ module a;
|
||||
void foo()(){}
|
||||
}.parseAndVisit(2);
|
||||
}
|
||||
|
||||
unittest
|
||||
{
|
||||
q{ module a;
|
||||
int foo(int){}
|
||||
}.parseAndVisit(2);
|
||||
}
|
||||
|
||||
unittest
|
||||
{
|
||||
q{ module a;
|
||||
class Foo(T, A...){}
|
||||
}.parseAndVisit(2);
|
||||
}
|
||||
|
||||
unittest
|
||||
{
|
||||
q{ module a;
|
||||
struct Foo(alias Fun, A...){}
|
||||
}.parseAndVisit(2);
|
||||
}
|
||||
|
|
@ -9,9 +9,10 @@ import
|
|||
import
|
||||
dparse.lexer, dparse.parser, dparse.ast, dparse.rollback_allocator;
|
||||
import
|
||||
common, todos, symlist, imports, mainfun, halstead;
|
||||
common, todos, symlist, imports, mainfun, halstead, ddoc_template;
|
||||
|
||||
|
||||
private __gshared int caretLine;
|
||||
private __gshared bool deepSymList;
|
||||
private __gshared static Appender!(ubyte[]) source;
|
||||
private __gshared static Appender!(AstErrors) errors;
|
||||
|
@ -50,7 +51,8 @@ void main(string[] args)
|
|||
|
||||
// options for the work
|
||||
getopt(args, std.getopt.config.passThrough,
|
||||
"d", &deepSymList
|
||||
"d", &deepSymList,
|
||||
"l", &caretLine
|
||||
);
|
||||
|
||||
// launch directly a work
|
||||
|
@ -60,6 +62,7 @@ void main(string[] args)
|
|||
"s", &handleSymListOption,
|
||||
"t", &handleTodosOption,
|
||||
"H", &handleHalsteadOption,
|
||||
"K", &handleDdocTemplateOption,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -137,6 +140,21 @@ void handleHalsteadOption()
|
|||
.performHalsteadMetrics;
|
||||
}
|
||||
|
||||
/// Handles the "-D" option: write the ddoc template for a given declaration
|
||||
void handleDdocTemplateOption()
|
||||
{
|
||||
mixin(logCall);
|
||||
|
||||
RollbackAllocator alloc;
|
||||
StringCache cache = StringCache(StringCache.defaultBucketCount);
|
||||
LexerConfig config = LexerConfig("", StringBehavior.source);
|
||||
|
||||
source.data
|
||||
.getTokensForParser(config, &cache)
|
||||
.parseModule("", &alloc, &ignoreErrors)
|
||||
.getDdocTemplate(caretLine);
|
||||
}
|
||||
|
||||
private void handleErrors(string fname, size_t line, size_t col, string message,
|
||||
bool err)
|
||||
{
|
||||
|
|
|
@ -22,6 +22,8 @@ procedure getModulesImports(const files: string; results: TStrings);
|
|||
|
||||
procedure getHalsteadMetrics(source: TStrings; out jsn: TJSONObject);
|
||||
|
||||
procedure getDdocTemplate(source, res: TStrings;caretLine: integer);
|
||||
|
||||
implementation
|
||||
|
||||
var
|
||||
|
@ -125,5 +127,30 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure getDdocTemplate(source, res: TStrings; caretLine: integer);
|
||||
var
|
||||
prc: TProcess;
|
||||
str: string;
|
||||
begin
|
||||
str := getToolName;
|
||||
if str.isEmpty then
|
||||
exit;
|
||||
prc := TProcess.Create(nil);
|
||||
try
|
||||
prc.Executable := str;
|
||||
prc.Parameters.Add('-K');
|
||||
prc.Parameters.Add('-l' + caretLine.ToString);
|
||||
prc.Options := [poUsePipes {$IFDEF WINDOWS}, poNewConsole{$ENDIF}];
|
||||
prc.ShowWindow := swoHIDE;
|
||||
prc.Execute;
|
||||
str := source.Text;
|
||||
prc.Input.Write(str[1], str.length);
|
||||
prc.CloseInput;
|
||||
processOutputToStrings(prc, res);
|
||||
finally
|
||||
prc.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
|
|
@ -155,6 +155,10 @@ inherited CEEditorWidget: TCEEditorWidget
|
|||
object MenuItem12: TMenuItem
|
||||
Caption = '-'
|
||||
end
|
||||
object mnuedDdocTmp: TMenuItem
|
||||
Caption = 'Insert DDOC template'
|
||||
OnClick = mnuedDdocTmpClick
|
||||
end
|
||||
object mnuedRename: TMenuItem
|
||||
Caption = 'Rename identifier'
|
||||
OnClick = mnuedRenameClick
|
||||
|
|
|
@ -58,6 +58,7 @@ type
|
|||
MenuItem10: TMenuItem;
|
||||
MenuItem11: TMenuItem;
|
||||
MenuItem12: TMenuItem;
|
||||
mnuedDdocTmp: TMenuItem;
|
||||
mnuedPrevProtGrp: TMenuItem;
|
||||
mnuedNextProtGrp: TMenuItem;
|
||||
MenuItem2: TMenuItem;
|
||||
|
@ -89,6 +90,7 @@ type
|
|||
macRecorder: TSynMacroRecorder;
|
||||
editorStatus: TStatusBar;
|
||||
mnuEditor: TPopupMenu;
|
||||
procedure mnuedDdocTmpClick(Sender: TObject);
|
||||
procedure mnuedPrevProtGrpClick(Sender: TObject);
|
||||
procedure mnuedNextProtGrpClick(Sender: TObject);
|
||||
procedure mnuedNextCareaClick(Sender: TObject);
|
||||
|
@ -900,6 +902,12 @@ begin
|
|||
fDoc.previousProtectionGroup;
|
||||
end;
|
||||
|
||||
procedure TCEEditorWidget.mnuedDdocTmpClick(Sender: TObject);
|
||||
begin
|
||||
if fDoc.isNotNil then
|
||||
fDoc.insertDdocTemplate;
|
||||
end;
|
||||
|
||||
procedure TCEEditorWidget.mnuedNextProtGrpClick(Sender: TObject);
|
||||
begin
|
||||
if fDoc.isNotNil then
|
||||
|
|
|
@ -12,7 +12,7 @@ uses
|
|||
md5,
|
||||
//SynEditMarkupFoldColoring,
|
||||
Clipbrd, fpjson, jsonparser, LazUTF8, LazUTF8Classes, Buttons, StdCtrls,
|
||||
ce_common, ce_writableComponent, ce_d2syn, ce_txtsyn, ce_dialogs,
|
||||
ce_common, ce_writableComponent, ce_d2syn, ce_txtsyn, ce_dialogs, ce_dastworx,
|
||||
ce_sharedres, ce_dlang, ce_stringrange, ce_dbgitf, ce_observer, ce_diff;
|
||||
|
||||
type
|
||||
|
@ -272,6 +272,7 @@ type
|
|||
procedure addCurLineBreakPoint;
|
||||
procedure removeCurLineBreakPoint;
|
||||
procedure toggleCurLineBreakpoint;
|
||||
procedure insertDdocTemplate;
|
||||
function implementMain: THasMain;
|
||||
procedure replaceUndoableContent(const value: string);
|
||||
//
|
||||
|
@ -346,6 +347,7 @@ const
|
|||
ecAddBreakpoint = ecUserFirst + 22;
|
||||
ecRemoveBreakpoint = ecUserFirst + 23;
|
||||
ecToggleBreakpoint = ecUserFirst + 24;
|
||||
ecInsertDdocTemplate = ecUserFirst + 25;
|
||||
|
||||
var
|
||||
D2Syn: TSynD2Syn; // used as model to set the options when no editor exists.
|
||||
|
@ -989,6 +991,7 @@ begin
|
|||
AddKey(ecAddBreakpoint, 0, [], 0, []);
|
||||
AddKey(ecRemoveBreakpoint, 0, [], 0, []);
|
||||
AddKey(ecToggleBreakpoint, 0, [], 0, []);
|
||||
AddKey(ecInsertDdocTemplate, 0, [], 0, []);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -1019,6 +1022,7 @@ begin
|
|||
'ecAddBreakpoint': begin Int := ecAddBreakpoint; exit(true); end;
|
||||
'ecRemoveBreakpoint': begin Int := ecRemoveBreakpoint; exit(true); end;
|
||||
'ecToggleBreakpoint': begin Int := ecToggleBreakpoint; exit(true); end;
|
||||
'ecInsertDdocTemplate': begin Int := ecInsertDdocTemplate; exit(true); end;
|
||||
else exit(false);
|
||||
end;
|
||||
end;
|
||||
|
@ -1050,6 +1054,7 @@ begin
|
|||
ecAddBreakpoint: begin Ident := 'ecAddBreakpoint'; exit(true); end;
|
||||
ecRemoveBreakpoint: begin Ident := 'ecRemoveBreakpoint'; exit(true); end;
|
||||
ecToggleBreakpoint: begin Ident := 'ecToggleBreakpoint'; exit(true); end;
|
||||
ecInsertDdocTemplate: begin Ident := 'ecInsertDdocTemplate'; exit(true); end;
|
||||
else exit(false);
|
||||
end;
|
||||
end;
|
||||
|
@ -1120,6 +1125,8 @@ begin
|
|||
removeCurLineBreakPoint;
|
||||
ecToggleBreakpoint:
|
||||
toggleCurLineBreakpoint;
|
||||
ecInsertDdocTemplate:
|
||||
insertDdocTemplate;
|
||||
end;
|
||||
if fOverrideColMode and not SelAvail then
|
||||
begin
|
||||
|
@ -1839,6 +1846,42 @@ begin
|
|||
else
|
||||
removeBreakPoint(CaretY);
|
||||
end;
|
||||
|
||||
procedure TCESynMemo.insertDdocTemplate;
|
||||
var
|
||||
d: TStringList;
|
||||
i: integer;
|
||||
j: integer;
|
||||
k: integer;
|
||||
s: string;
|
||||
p: TPoint;
|
||||
begin
|
||||
d := TStringList.Create;
|
||||
try
|
||||
getDdocTemplate(lines, d, CaretY);
|
||||
if d.Text.isNotEmpty then
|
||||
begin
|
||||
BeginUndoBlock;
|
||||
ExecuteCommand(ecLineStart, #0, nil);
|
||||
k := CaretX;
|
||||
p.y:= CaretY -1 ;
|
||||
p.x:= 1 ;
|
||||
ExecuteCommand(ecGotoXY, #0, @p);
|
||||
for i := 0 to d.Count-1 do
|
||||
begin
|
||||
s := d[i];
|
||||
ExecuteCommand(ecLineBreak, #0, nil);
|
||||
while caretX < k do
|
||||
ExecuteCommand(ecTab, #0, nil);
|
||||
for j := 1 to s.length do
|
||||
ExecuteCommand(ecChar, s[j], nil);
|
||||
end;
|
||||
EndUndoBlock;
|
||||
end;
|
||||
finally
|
||||
d.Free;
|
||||
end;
|
||||
end;
|
||||
{$ENDREGION}
|
||||
|
||||
{$REGION DDoc & CallTip --------------------------------------------------------}
|
||||
|
|
Loading…
Reference in New Issue