From 2a47f9b5efd237d821668093d5902ced4bda92d4 Mon Sep 17 00:00:00 2001 From: Daniel Kapla Date: Sun, 7 Jan 2018 14:44:53 +0100 Subject: [PATCH] add: Compile Commands --- dictionary/documentclass_symbols.ts | 10 + dictionary/environment_symbols.ts | 89 +++-- dictionary/math_symbols.ts | 14 +- dictionary/parameter_dictionary.ts | 3 +- dictionary/preamble_symbols.ts | 6 +- dictionary/text_symbols.ts | 144 +++++--- dictionary/tikz_symbols.ts | 10 +- package.json | 30 +- scripts/makeindex.sh | 20 + scripts/pdflatex.sh | 23 ++ snippets/LaTeX.json | 18 +- src/commands.ts | 50 +++ src/completionItemProvider.ts | 554 ++++++++++++++-------------- src/extension.ts | 27 +- 14 files changed, 591 insertions(+), 407 deletions(-) create mode 100644 dictionary/documentclass_symbols.ts create mode 100755 scripts/makeindex.sh create mode 100755 scripts/pdflatex.sh create mode 100644 src/commands.ts diff --git a/dictionary/documentclass_symbols.ts b/dictionary/documentclass_symbols.ts new file mode 100644 index 0000000..a7677cf --- /dev/null +++ b/dictionary/documentclass_symbols.ts @@ -0,0 +1,10 @@ +import { latex_types } from "./symbol_types"; + +export default { + article: { documentation: "for articles, the most commonly used class", kind: latex_types.environment }, + report: { documentation: "variant of article for a report", kind: latex_types.environment }, + letter: { documentation: "for letters", kind: latex_types.environment }, + book: { documentation: "for chapters of a book", kind: latex_types.environment }, + proc: { documentation: "for proceedings, based on article", kind: latex_types.environment }, + slides: { documentation: "to produce transparencies", kind: latex_types.environment }, +}; diff --git a/dictionary/environment_symbols.ts b/dictionary/environment_symbols.ts index 7306df8..9d142dc 100644 --- a/dictionary/environment_symbols.ts +++ b/dictionary/environment_symbols.ts @@ -1,50 +1,65 @@ import { latex_types } from "./symbol_types"; export default { - "displaymath": { insertText: "displaymath", details: "math environment", documentation: "displaymath", kind: latex_types.environment }, - "align": { insertText: "align", details: "math environment", documentation: "align", kind: latex_types.environment }, - "align*": { insertText: "align*", details: "math environment", documentation: "align*", kind: latex_types.environment }, - "flalign": { insertText: "flalign", details: "math environment", documentation: "flalign", kind: latex_types.environment }, - "flalign*": { insertText: "flalign*", details: "math environment", documentation: "flalign*", kind: latex_types.environment }, - "gather": { insertText: "gather", details: "math environment", documentation: "gather", kind: latex_types.environment }, - "gather*": { insertText: "gather*", details: "math environment", documentation: "gather*", kind: latex_types.environment }, - "equation": { insertText: "equation", details: "math environment", documentation: "equation", kind: latex_types.environment }, - "multline": { insertText: "multline", details: "math environment", documentation: "multline", kind: latex_types.environment }, - "split": { insertText: "split", details: "math environment", documentation: "split", kind: latex_types.environment }, + displaymath: { insertText: "displaymath", detail: "math environment", documentation: "displaymath", kind: latex_types.environment }, + align: { insertText: "align", detail: "math environment", documentation: "align", kind: latex_types.environment }, + "align*": { insertText: "align*", detail: "math environment", documentation: "align*", kind: latex_types.environment }, + flalign: { insertText: "flalign", detail: "math environment", documentation: "flalign", kind: latex_types.environment }, + "flalign*": { insertText: "flalign*", detail: "math environment", documentation: "flalign*", kind: latex_types.environment }, + gather: { insertText: "gather", detail: "math environment", documentation: "gather", kind: latex_types.environment }, + "gather*": { insertText: "gather*", detail: "math environment", documentation: "gather*", kind: latex_types.environment }, + equation: { insertText: "equation", detail: "math environment", documentation: "equation", kind: latex_types.environment }, + multline: { insertText: "multline", detail: "math environment", documentation: "multline", kind: latex_types.environment }, + split: { insertText: "split", detail: "math environment", documentation: "split", kind: latex_types.environment }, - "itemize": { insertText: "itemize", detail: "Use \\item for list entrie", documentation: "Creates a simple List.", kind: latex_types.environment }, - "enumerate": { insertText: "enumerate", detail: "Use \\item for list entrie", documentation: "Creates a numbered List.", kind: latex_types.environment }, - "description": { insertText: "description", detail: "Use \\item[element] for a discription entrie", documentation: "Creates a List of \"element\" discriptions.", kind: latex_types.environment }, - - "flushleft": { insertText: "flushleft", documentation: "Alignes Text left.", kind: latex_types.environment }, - "flusright": { insertText: "flusright", documentation: "Alignes Text right.", kind: latex_types.environment }, - "center": { insertText: "center", documentation: "Alignes Text centered.", kind: latex_types.environment }, + minipage: { insertText: "minipage", detail: "\\begin{minipage}[]{} ... \\end{minipage}", documentation: "minipage", kind: latex_types.environment }, - "quotation": { insertText: "quotation", documentation: "The quotation environment is useful for longer quotes going over several paragraphs, because it indents the first line of each paragraph.", kind: latex_types.environment }, - "verse": { insertText: "verse", documentation: "The verse environment is useful for poems where the line breaks are important. The lines are separated by issuing a \\\\ at the end of a line and an empty line after each verse.", kind: latex_types.environment }, - "abstract": { insertText: "abstract", documentation: "An environment for an abstract.", kind: latex_types.environment }, - - "tikzpicture": { insertText: "tikzpicture", documentation: "The \"TeX Ist Kein Zeichnprogram\" environment\nNeeds \\usepackage{tikz}", kind: latex_types.environment }, + itemize: { insertText: "itemize", detail: "Use \\item for list entrie", documentation: "Creates a simple List.", kind: latex_types.environment }, + enumerate: { insertText: "enumerate", detail: "Use \\item for list entrie", documentation: "Creates a numbered List.", kind: latex_types.environment }, + description: { insertText: "description", detail: "Use \\item[element] for a discription entrie", documentation: "Creates a List of \"element\" discriptions.", kind: latex_types.environment }, - "verbatim": { insertText: "verbatim", detail: "Do not use verbatim environment and the \\verb command within parameters of other commands.", documentation: "Environment content will be directly printed, as if typed on a typewriter, with all line breaks and spaces, without any LaTeX command being executed.", kind: latex_types.environment }, - "verbatim*": { insertText: "verbatim*", detail: "Do not use verbatim environment and the \\verb command within parameters of other commands.", documentation: "Environment content will be directly printed, as if typed on a typewriter, with all line breaks and spaces, without any LaTeX command being executed. The additional * lets spaces be printed visible.", kind: latex_types.environment }, - - "tabular": { insertText: "tabular", detail: "Use \"&\" for jump to the next column, \"\\\\\" for a line break and \"\\hline\" for inserts a horizontal line", documentation: "The table spec argument of the \\begin{tabular}[pos]{table spec} command defines the format of the table. Use an \"l\" for a column of left-aligned text, \"r\" for right-aligned text, and \"c\" for centred text; p{width} for a column containing justified text with line breaks, and \"|\" for a vertical line. The pos argument specifies the vertical position of the table relative to the baseline of the surrounding text. Use either of the letters \"t\", \"b\" or \"c\" to specify table alignment at the top, bottom or center. The column separator can be specified with the @{...} construct. This command kills the inter-column space and replaces it with whatever is between the curly braces.", kind: latex_types.environment }, + flushleft: { insertText: "flushleft", documentation: "Alignes Text left.", kind: latex_types.environment }, + flusright: { insertText: "flusright", documentation: "Alignes Text right.", kind: latex_types.environment }, + center: { insertText: "center", documentation: "Alignes Text centered.", kind: latex_types.environment }, - "figure": { insertText: "figure", documentation: "Any material enclosed in a \"figure\" or \"table\" environment will be treated as floating matter. Both float environments support an optional parameter called the placement specifier. The placement specifier is a combination of \"h\" \(hier\), \"b\" \(bottom\), \"p\" \(page\), \"!\" \(without considering most of the internal parameters\)].", kind: latex_types.environment }, + quotation: { insertText: "quotation", documentation: "The quotation environment is useful for longer quotes going over several paragraphs, because it indents the first line of each paragraph.", kind: latex_types.environment }, + verse: { insertText: "verse", documentation: "The verse environment is useful for poems where the line breaks are important. The lines are separated by issuing a \\\\ at the end of a line and an empty line after each verse.", kind: latex_types.environment }, + abstract: { insertText: "abstract", documentation: "An environment for an abstract.", kind: latex_types.environment }, - "cases": { insertText: "cases", documentation: "cases", kind: latex_types.environment }, + tikzpicture: { insertText: "tikzpicture", documentation: "The \"TeX Ist Kein Zeichnprogram\" environment\nNeeds \\usepackage{tikz}", kind: latex_types.environment }, - "array": { insertText: "array", documentation: "The \\\\begin{array}{line-positioning} command with \"line-positioning\" is \"l\" \(left\), \"c\" \(richt\) or \"r\" \(right\) for each column. Use \"&\" to for next column and \"\\\\\" for linebreaks.", kind: latex_types.environment }, - "matrix": { insertText: "matrix", detail: "max 10 column", documentation: "Matrix without delimiters.", kind: latex_types.environment }, - "pmatrix": { insertText: "pmatrix", detail: "max 10 column", documentation: "Matrix with \( as delimiters.", kind: latex_types.environment }, - "bmatrix": { insertText: "bmatrix", detail: "max 10 column", documentation: "Matrix with [ as delimiters.", kind: latex_types.environment }, - "Bmatrix": { insertText: "Bmatrix", detail: "max 10 column", documentation: "Matrix with { as delimiters.", kind: latex_types.environment }, - "vmatrix": { insertText: "vmatrix", detail: "max 10 column", documentation: "Matrix with | as delimiters.", kind: latex_types.environment }, - "Vmatrix": { insertText: "Vmatrix", detail: "max 10 column", documentation: "Matrix with || as delimiters.", kind: latex_types.environment }, + verbatim: { insertText: "verbatim", detail: "Do not use verbatim environment and the \\verb command within parameters of other commands.", documentation: "Environment content will be directly printed, as if typed on a typewriter, with all line breaks and spaces, without any LaTeX command being executed.", kind: latex_types.environment }, + "verbatim*": { insertText: "verbatim*", detail: "Do not use verbatim environment and the \\verb command within parameters of other commands.", documentation: "Environment content will be directly printed, as if typed on a typewriter, with all line breaks and spaces, without any LaTeX command being executed. The additional * lets spaces be printed visible.", kind: latex_types.environment }, - "tizkpicture": { insertText: "tizkpicture", detail: "Requires Package \"tikz\"", documentation: "", kind: latex_types.environment }, + tabular: { insertText: "tabular", detail: "Use \"&\" for jump to the next column, \"\\\\\" for a line break and \"\\hline\" for inserts a horizontal line", documentation: "The table spec argument of the \\begin{tabular}[pos]{table spec} command defines the format of the table. Use an \"l\" for a column of left-aligned text, \"r\" for right-aligned text, and \"c\" for centred text; p{width} for a column containing justified text with line breaks, and \"|\" for a vertical line. The pos argument specifies the vertical position of the table relative to the baseline of the surrounding text. Use either of the letters \"t\", \"b\" or \"c\" to specify table alignment at the top, bottom or center. The column separator can be specified with the @{...} construct. This command kills the inter-column space and replaces it with whatever is between the curly braces.", kind: latex_types.environment }, + + figure: { documentation: "Any material enclosed in a \"figure\" or \"table\" environment will be treated as floating matter. Both float environments support an optional parameter called the placement specifier. The placement specifier is a combination of \"h\" \(hier\), \"b\" \(bottom\), \"p\" \(page\), \"!\" \(without considering most of the internal parameters\)].", kind: latex_types.environment }, + + cases: { documentation: "cases", kind: latex_types.environment }, + + array: { documentation: "The \\\\begin{array}{line-positioning} command with \"line-positioning\" is \"l\" \(left\), \"c\" \(richt\) or \"r\" \(right\) for each column. Use \"&\" to for next column and \"\\\\\" for linebreaks.", kind: latex_types.environment }, + matrix: { detail: "max 10 column", documentation: "Matrix without delimiters.", kind: latex_types.environment }, + pmatrix: { detail: "max 10 column", documentation: "Matrix with \( as delimiters.", kind: latex_types.environment }, + bmatrix: { detail: "max 10 column", documentation: "Matrix with [ as delimiters.", kind: latex_types.environment }, + Bmatrix: { detail: "max 10 column", documentation: "Matrix with { as delimiters.", kind: latex_types.environment }, + vmatrix: { detail: "max 10 column", documentation: "Matrix with | as delimiters.", kind: latex_types.environment }, + Vmatrix: { detail: "max 10 column", documentation: "Matrix with || as delimiters.", kind: latex_types.environment }, + + tizkpicture: { insertText: "tizkpicture", detail: "Requires Package \"tikz\"", documentation: "", kind: latex_types.environment }, + + lstlisting: { insertText: "lstlisting", detail: "Requires Package \"listings\"", documentation: "", kind: latex_types.environment }, + + + rmfamily: { documentation: "Font: Roman.", kind: latex_types.environment }, + itshape: { documentation: "Font: Italics.", kind: latex_types.environment }, + mdseries: { documentation: "Font: Medium weight (default).", kind: latex_types.environment }, + bfseries: { documentation: "Font: Boldface.", kind: latex_types.environment }, + upshape: { documentation: "Font: Upright (default).", kind: latex_types.environment }, + slshape: { documentation: "Font: Slanted.", kind: latex_types.environment }, + sffamily: { documentation: "Font: Sans serif.", kind: latex_types.environment }, + scshape: { documentation: "Font: Small caps.", kind: latex_types.environment }, + ttfamily: { documentation: "Font: Typewriter.", kind: latex_types.environment }, + normalfont: { documentation: "Font: Main document font.", kind: latex_types.environment }, - "lstlisting": { insertText: "lstlisting", detail: "Requires Package \"listings\"", documentation: "", kind: latex_types.environment }, }; diff --git a/dictionary/math_symbols.ts b/dictionary/math_symbols.ts index ae0b1a5..61d73c5 100644 --- a/dictionary/math_symbols.ts +++ b/dictionary/math_symbols.ts @@ -4,7 +4,14 @@ var required_latexsym = "Required package \"latexsym\""; var required_amsmath = "Required package \"amsmath\""; export default { - "operatorname": { insertText: "operatorname{$1}$0", documentation: "displays content as operator", kind: latex_types.function }, + begin: { + detail: "\\begin{} ... \\end{}", + insertText: "begin{$1}\n\t$0\n\\end{$1}", + documentation: "Environment Snippet", + kind: latex_types.snippet + }, + + operatorname: { insertText: "operatorname{$1}$0", documentation: "displays content as operator", kind: latex_types.function }, "label": { insertText: "label{$1}$0", documentation: "Creates a reference with a number to refere it by the \"ref\" command.", kind: latex_types.keyword }, "tag": { insertText: "tag{$1}$0", documentation: "Creates a reference with name to refere it by the \"ref\" command by the taged name.", kind: latex_types.keyword }, @@ -26,8 +33,9 @@ export default { "cfrac": { insertText: "cfrac{$1}{$2}$0", documentation: "Continued Fraction", kind: latex_types.function }, "tfrac": { insertText: "tfrac{$1}{$2}$0", documentation: "Text style Fraction", kind: latex_types.function }, "dfrac": { insertText: "dfrac{$1}{$2}$0", documentation: "Display style Fraction", kind: latex_types.function }, - "genfrac": { insertText: "\genfrac{${1:left-delim}}{${2:right-delim}}{${3:thickness}}{${4:mathstyle}}{${5:numerator}}{${6:denominator}}$0", documentation: "Generic Fraction", kind: latex_types.function }, - "sqrt": { insertText: "sqrt[]{$1}$0", documentation: "Root (Square Root)", kind: latex_types.function }, + "genfrac": { insertText: "\\genfrac{${1:left-delim}}{${2:right-delim}}{${3:thickness}}{${4:mathstyle}}{${5:numerator}}{${6:denominator}}$0", documentation: "Generic Fraction", detail: "\\genfrac{}{}{}{}{}{}", kind: latex_types.function }, + "sqrt": { insertText: "sqrt{$1}$0", documentation: "square root", kind: latex_types.function }, + "sqrt[]": { insertText: "sqrt[]{$1}$0", detail: "\\sqrt[]{}", documentation: "The -th root of .", kind: latex_types.function }, "lim": { insertText: "lim_{$1}$0", documentation: "Limes", kind: latex_types.function }, "sup": { insertText: "sup_{$1}$0", documentation: "sup", kind: latex_types.function }, diff --git a/dictionary/parameter_dictionary.ts b/dictionary/parameter_dictionary.ts index 2cd8f22..0ee44d0 100644 --- a/dictionary/parameter_dictionary.ts +++ b/dictionary/parameter_dictionary.ts @@ -225,7 +225,6 @@ var node_options = { }; export default { - node: node_options, coordinate: node_options, @@ -239,6 +238,8 @@ export default { clip: path_options, useasboundingbox: path_options, + plot: path_options, + "begin{figure}": { "!": { documentation: "overwrite" }, "h": { documentation: "hier" }, diff --git a/dictionary/preamble_symbols.ts b/dictionary/preamble_symbols.ts index eb716e2..9563fe9 100644 --- a/dictionary/preamble_symbols.ts +++ b/dictionary/preamble_symbols.ts @@ -4,9 +4,9 @@ var preamble = "Define in preamble!"; export default { documentclass: { - insertText: "documentclass", - kind: latex_types.keyword - }, + insertText: "documentclass", + kind: latex_types.keyword + }, usepackage: { insertText: "usepackage{$1}", diff --git a/dictionary/text_symbols.ts b/dictionary/text_symbols.ts index ff51a95..d521dab 100644 --- a/dictionary/text_symbols.ts +++ b/dictionary/text_symbols.ts @@ -1,76 +1,106 @@ import { latex_types } from "./symbol_types"; export default { + begin: { + detail: "\\begin{} ... \\end{}", + insertText: "begin{$1}\n\t$0\n\\end{$1}", + documentation: "Environment Snippet", + kind: latex_types.snippet + }, + input: { - detail: "\\input{}", - insertText: "input{${0:}}", - documentation: "Includes the sourcecode from the target .tex file.", + detail: "\\input{}", + insertText: "input{${0:}}", + documentation: "Includes the sourcecode from the target .tex file.", kind: latex_types.keyword - }, + }, include: { - detail: "\\include{}", - insertText: "include{${0:}}", - documentation: "Includes the rendered content from the target .tex file on a new page. Note: If \\includeonly is specified in the preamble, all NOT specified files are ignored.", + detail: "\\include{}", + insertText: "include{${0:}}", + documentation: "Includes the rendered content from the target .tex file on a new page. Note: If \\includeonly is specified in the preamble, all NOT specified files are ignored.", kind: latex_types.keyword - }, - includegraphics: { - detail: "\\includegraphics[=,...]{}\nRequired package \"graphicx\"", - insertText: "includegraphics[$1]{${0:}}", - documentation: "Use the command \\includegraphics[=,...]{} to include into your document. The optional parameter accepts a comma separated list of 's and associated 's. The 's can be used to alter the width, height and rotation of the included graphic.", + }, + includegraphics: { + detail: "\\includegraphics[=,...]{}\nRequired package \"graphicx\"", + insertText: "includegraphics[$1]{${0:}}", + documentation: "Use the command \\includegraphics[=,...]{} to include into your document. The optional parameter accepts a comma separated list of 's and associated 's. The 's can be used to alter the width, height and rotation of the included graphic.", kind: latex_types.keyword - }, - verbatiminput: { - detail: "\\verbatiminput{}\nRequired package \"verbatim\"", - insertText: "verbatiminput{${0:}}", - documentation: "Allows to include raw ASCII text into your document as if it was inside a verbatim environment.", - kind: latex_types.keyword - }, + }, + verbatiminput: { + detail: "\\verbatiminput{}\nRequired package \"verbatim\"", + insertText: "verbatiminput{${0:}}", + documentation: "Allows to include raw ASCII text into your document as if it was inside a verbatim environment.", + kind: latex_types.keyword + }, + lstinputlisting: { + detail: "\\lstinputlisting{}\nRequired package \"lstlisting\"", + insertText: "lstinputlisting{${0:}}", + documentation: "Allows to include Source Code.", + kind: latex_types.keyword + }, - "usepackage": { insertText: "usepackage{$1}", documentation: "usepackage", kind: latex_types.keyword }, - "newenvironment": { insertText: "newenvironment{${1:name}}[$2]{$3}{$0}", documentation: "newenvironment", kind: latex_types.keyword }, - "newcommand": { insertText: "newcommand{${1:name}}[$2]{$3}", documentation: "newcommand", kind: latex_types.keyword }, - "renewcommand": { insertText: "renewcommand{${1:name}}[$2]{$3}", documentation: "renewcommand", kind: latex_types.keyword }, + "usepackage": { insertText: "usepackage{$1}", documentation: "usepackage", kind: latex_types.keyword }, + "newenvironment": { insertText: "newenvironment{${1:name}}[$2]{$3}{$0}", documentation: "newenvironment", kind: latex_types.keyword }, + "newcommand": { insertText: "newcommand{${1:name}}[$2]{$3}", documentation: "newcommand", kind: latex_types.keyword }, + "renewcommand": { insertText: "renewcommand{${1:name}}[$2]{$3}", documentation: "renewcommand", kind: latex_types.keyword }, - "today": { insertText: "today", documentation: "The current Date", kind: latex_types.symbol }, - "TeX": { insertText: "TeX", documentation: "The TeX symbol", kind: latex_types.symbol }, - "LaTeX": { insertText: "LaTeX", documentation: "The LaTeX symbol", kind: latex_types.symbol }, - "LaTeXe": { insertText: "LaTeXe", documentation: "The current LaTeX symbol", kind: latex_types.symbol }, + "today": { insertText: "today", documentation: "The current Date", kind: latex_types.symbol }, + "TeX": { insertText: "TeX", documentation: "The TeX symbol", kind: latex_types.symbol }, + "LaTeX": { insertText: "LaTeX", documentation: "The LaTeX symbol", kind: latex_types.symbol }, + "LaTeXe": { insertText: "LaTeXe", documentation: "The current LaTeX symbol", kind: latex_types.symbol }, - "newline": { insertText: "newline", documentation: "Starts a new line", kind: latex_types.keyword }, - "newpage": { insertText: "newpage", documentation: "Starts a new page", kind: latex_types.keyword }, - "linebreak": { insertText: "newpage[]", detail: "Optional Param: int 0-4.", documentation: "Suggests a line break to the LaTeX compiler. Optional parameter: int from 0 to 4, a value lower 4 may be ignored if it would look bad.", kind: latex_types.keyword }, - "nolinebreak": { insertText: "nolinebreak[]", detail: "Optional Param: int 0-4.", documentation: "Suggests no line break to the LaTeX compiler. Optional parameter: int from 0 to 4, a value lower 4 may be ignored if it would look bad.", kind: latex_types.keyword }, - "pagebreak": { insertText: "nolinebreak[]", detail: "Optional Param: int 0-4.", documentation: "Suggests a page break to the LaTeX compiler. Optional parameter: int from 0 to 4, a value lower 4 may be ignored if it would look bad.", kind: latex_types.keyword }, - "nopagebreak": { insertText: "nolinebreak[]", detail: "Optional Param: int 0-4.", documentation: "Suggests no page break to the LaTeX compiler. Optional parameter: int from 0 to 4, a value lower 4 may be ignored if it would look bad.", kind: latex_types.keyword }, + "newline": { insertText: "newline", documentation: "Starts a new line", kind: latex_types.keyword }, + "newpage": { insertText: "newpage", documentation: "Starts a new page", kind: latex_types.keyword }, + "linebreak": { insertText: "newpage[]", detail: "Optional Param: int 0-4.", documentation: "Suggests a line break to the LaTeX compiler. Optional parameter: int from 0 to 4, a value lower 4 may be ignored if it would look bad.", kind: latex_types.keyword }, + "nolinebreak": { insertText: "nolinebreak[]", detail: "Optional Param: int 0-4.", documentation: "Suggests no line break to the LaTeX compiler. Optional parameter: int from 0 to 4, a value lower 4 may be ignored if it would look bad.", kind: latex_types.keyword }, + "pagebreak": { insertText: "nolinebreak[]", detail: "Optional Param: int 0-4.", documentation: "Suggests a page break to the LaTeX compiler. Optional parameter: int from 0 to 4, a value lower 4 may be ignored if it would look bad.", kind: latex_types.keyword }, + "nopagebreak": { insertText: "nolinebreak[]", detail: "Optional Param: int 0-4.", documentation: "Suggests no page break to the LaTeX compiler. Optional parameter: int from 0 to 4, a value lower 4 may be ignored if it would look bad.", kind: latex_types.keyword }, - "section": { insertText: "section{$1}", documentation: "Section", kind: latex_types.keyword }, - "section*": { insertText: "section*{$1}", documentation: "Section", kind: latex_types.keyword }, - "subsection": { insertText: "subsection{$1}", documentation: "Sub Section", kind: latex_types.keyword }, - "subsection*": { insertText: "subsection*{$1}", documentation: "Sub Section", kind: latex_types.keyword }, - "subsubsection": { insertText: "subsubsection{$1}", documentation: "Sub Sub Section", kind: latex_types.keyword }, - "subsubsection*": { insertText: "subsubsection*{$1}", documentation: "Sub Sub Section", kind: latex_types.keyword }, - "paragraph": { insertText: "paragraph{$1}", documentation: "paragraph", kind: latex_types.keyword }, - "paragraph*": { insertText: "paragraph*{$1}", documentation: "paragraph", kind: latex_types.keyword }, + "section": { insertText: "section{$1}", documentation: "Section", kind: latex_types.keyword }, + "section*": { insertText: "section*{$1}", documentation: "Section", kind: latex_types.keyword }, + "subsection": { insertText: "subsection{$1}", documentation: "Sub Section", kind: latex_types.keyword }, + "subsection*": { insertText: "subsection*{$1}", documentation: "Sub Section", kind: latex_types.keyword }, + "subsubsection": { insertText: "subsubsection{$1}", documentation: "Sub Sub Section", kind: latex_types.keyword }, + "subsubsection*": { insertText: "subsubsection*{$1}", documentation: "Sub Sub Section", kind: latex_types.keyword }, + "paragraph": { insertText: "paragraph{$1}", documentation: "paragraph", kind: latex_types.keyword }, + "paragraph*": { insertText: "paragraph*{$1}", documentation: "paragraph", kind: latex_types.keyword }, - "label": { insertText: "label{$1}$0", documentation: "Label", kind: latex_types.keyword }, - "ref": { insertText: "ref{$1}$0", documentation: "Reference", kind: latex_types.keyword }, - "eqref": { insertText: "eqref{$1}$0", documentation: "Equation reference", kind: latex_types.keyword }, - "pageref": { insertText: "pageref{$1}$0", documentation: "Page reference", kind: latex_types.keyword }, - "index": { insertText: "index{$1}$0", documentation: "Creates a index Entrie", kind: latex_types.keyword }, + "label": { insertText: "label{$1}$0", documentation: "Label", kind: latex_types.keyword }, + "ref": { insertText: "ref{$1}$0", documentation: "Reference", kind: latex_types.keyword }, + "eqref": { insertText: "eqref{$1}$0", documentation: "Equation reference", kind: latex_types.keyword }, + "pageref": { insertText: "pageref{$1}$0", documentation: "Page reference", kind: latex_types.keyword }, + "index": { insertText: "index{$1}$0", documentation: "Creates a index Entrie", kind: latex_types.keyword }, - "emph": { insertText: "emph{$1}$0", documentation: "Emphasize Text", kind: latex_types.function }, - "texttt": { insertText: "texttt{$1}$0", documentation: "Typeset Text", kind: latex_types.function }, - "textit": { insertText: "textit{$1}$0", documentation: "Italic Text", kind: latex_types.function }, - "textbf": { insertText: "textbf{$1}$0", documentation: "Bold Text", kind: latex_types.function }, - "underline": { insertText: "underline{$1}$0", documentation: "Bold Text", kind: latex_types.function }, + emph: { insertText: "emph{$1}$0", documentation: "Emphasize Text", kind: latex_types.function }, + underline: { insertText: "underline{$1}$0", documentation: "Bold Text", kind: latex_types.function }, + textrm: { insertText: "textrm{$1}$0", documentation: "Font: Roman", kind: latex_types.function }, + rmfamily: { detail: "{\\rmfamily ... }", documentation: "Font: Roman", kind: latex_types.keyword }, + textit: { insertText: "textit{$1}$0", documentation: "Font: Italic", kind: latex_types.function }, + itshape: { detail: "{\\itshape ... }", documentation: "Font: Italic", kind: latex_types.keyword }, + textmd: { insertText: "textmd{$1}$0", documentation: "Font: Medium weight", kind: latex_types.function }, + mdseries: { detail: "{\\mdseries ... }", documentation: "Font: Medium weight", kind: latex_types.keyword }, + textbf: { insertText: "textbf{$1}$0", documentation: "Font: Boldface", kind: latex_types.function }, + bfseries: { detail: "{\\bfseries ... }", documentation: "Font: Boldface", kind: latex_types.keyword }, + textup: { insertText: "textup{$1}$0", documentation: "Font: Upright", kind: latex_types.function }, + upshape: { detail: "{\\upshape ... }", documentation: "Font: Upright", kind: latex_types.keyword }, + textsl: { insertText: "textsl{$1}$0", documentation: "Font: Slanted", kind: latex_types.function }, + slshape: { detail: "{\\slshape ... }", documentation: "Font: Slanted", kind: latex_types.keyword }, + textsf: { insertText: "textsf{$1}$0", documentation: "Font: Sans serif", kind: latex_types.function }, + sffamily: { detail: "{\\sffamily ... }", documentation: "Font: Sans serif", kind: latex_types.keyword }, + textsc: { insertText: "textsc{$1}$0", documentation: "Font: Small caps", kind: latex_types.function }, + scshape: { detail: "{\\scshape ... }", documentation: "Font: Small caps", kind: latex_types.keyword }, + texttt: { insertText: "texttt{$1}$0", documentation: "Font: Typewriter", kind: latex_types.function }, + ttfamily: { detail: "{\\ttfamily ... }", documentation: "Font: Typewriter", kind: latex_types.keyword }, + textnormal: { insertText: "textnormal{$1}$0", documentation: "Font: Normal", kind: latex_types.function }, + normalfont: { detail: "{\\normalfont ... }", documentation: "Font: Normal", kind: latex_types.keyword }, - // TODO: need a specific type in different environments!!! - "centering": { insertText: "centering", documentation: "Centers the content of figure or minipage content", kind: latex_types.keyword }, - "caption": { insertText: "caption{$1}$0", documentation: "Figure description", kind: latex_types.function }, + // TODO: need a specific type in different environments!!! + "centering": { insertText: "centering", documentation: "Centers the content of figure or minipage content", kind: latex_types.keyword }, + "caption": { insertText: "caption{$1}$0", documentation: "Figure description", kind: latex_types.function }, - "verb": { insertText: "verb{$1}$0", detail: "Do not use verbatim environment and the \\verb command within parameters of other commands.", documentation: "Environment content will be directly printed, as if typed on a typewriter, with all line breaks and spaces, without any LaTeX command being executed.", kind: latex_types.environment }, - "verb*": { insertText: "verb*{$1}$0", detail: "Do not use verbatim environment and the \\verb command within parameters of other commands.", documentation: "Environment content will be directly printed, as if typed on a typewriter, with all line breaks and spaces, without any LaTeX command being executed. The additional * lets spaces be printed visible.", kind: latex_types.environment }, + "verb": { insertText: "verb{$1}$0", detail: "Do not use verbatim environment and the \\verb command within parameters of other commands.", documentation: "Environment content will be directly printed, as if typed on a typewriter, with all line breaks and spaces, without any LaTeX command being executed.", kind: latex_types.environment }, + "verb*": { insertText: "verb*{$1}$0", detail: "Do not use verbatim environment and the \\verb command within parameters of other commands.", documentation: "Environment content will be directly printed, as if typed on a typewriter, with all line breaks and spaces, without any LaTeX command being executed. The additional * lets spaces be printed visible.", kind: latex_types.environment }, - "ldots": { insertText: "ldots", documentation: "3 lower dots", kind: latex_types.symbol }, + "ldots": { insertText: "ldots", documentation: "3 lower dots", kind: latex_types.symbol }, }; diff --git a/dictionary/tikz_symbols.ts b/dictionary/tikz_symbols.ts index b83a485..38d1dee 100644 --- a/dictionary/tikz_symbols.ts +++ b/dictionary/tikz_symbols.ts @@ -34,7 +34,15 @@ export default { draw: { documentation: "Inside {tikzpicture} this is an abbreviation for \path[draw].", kind: latex_types.keyword, - additionalInserts: [ { label: "draw[]", insertText: "draw[${1:}] $0", kind: latex_types.snippet } ] + additionalInserts: [ { + label: "draw[]", + insertText: "draw[${1:}] $0", + kind: latex_types.snippet + }, { + label: "draw plot", + insertText: "draw[${1:}, domain=${2:}:${3:}] plot (\\x, {${4:}});$0", + kind: latex_types.snippet + } ] }, fill: { documentation: "Inside {tikzpicture} this is an abbreviation for \path[fill].", diff --git a/package.json b/package.json index 791805a..e30291f 100644 --- a/package.json +++ b/package.json @@ -43,20 +43,36 @@ "TeX" ], "contributes": { + "keybindings": [ + { + "key": "ctrl+shift+b", + "command": "latex.pdflatex", + "when": "editorLangId == 'latex'" + } + ], + "commands": [ + { + "command": "latex.pdflatex", + "title": "pdflatex", + "category": "LaTeX" + }, { + "command": "latex.makeindex", + "title": "makeindex", + "category": "LaTeX" + } + ], "languages": [ { "id": "bibtex", "aliases": [ "BibTeX" ], "extensions": [ ".bib" ], "configuration": "./settings/BibTeX-configuration.json" - }, - { + }, { "id": "latex", "aliases": [ "LaTeX" ], "extensions": [ "bbx", "cbx", "cls", "ltx", "lco", "sty", "tex", "tikz" ], "configuration": "./settings/LaTeX-configuration.json" - }, - { + }, { "id": "tex", "aliases": [ "TeX" ], "extensions": [ "dtx", "ins" ], @@ -68,13 +84,11 @@ "language": "bibtex", "scopeName": "text.bibtex", "path": "./grammars/BibTeX.json" - }, - { + }, { "language": "latex", "scopeName": "text.tex.latex", "path": "./grammars/LaTeX.json" - }, - { + }, { "language": "tex", "scopeName": "text.tex", "path": "./grammars/TeX.json" diff --git a/scripts/makeindex.sh b/scripts/makeindex.sh new file mode 100755 index 0000000..2387363 --- /dev/null +++ b/scripts/makeindex.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +FILEDIRNAME=$1 +FILE=$2 +echo "fileDirname : $FILEDIRNAME" +echo "file : $FILE" + +if [ ${FILE: -4} == ".tex" ]; then + cd "$FILEDIRNAME" + FILE=${FILE##*/} # remove directory path from filename + makeindex "${FILE%.tex}.idx" > ~/.vscode/.makeindex_log # ${FILE%.tex}.idx replaces .tex ending with .idx + if [ $? == 0 ]; then # check success status (return value) of the last command (pdflatex) + echo -e "\033[32mCreated \"${FILE%.*}.idx\" successfully.\033[0m"; + else + cat ~/.vscode/.makeindex_log + echo -e "\033[31mERROR: Make Index for \"${FILE}\" failed.\033[0m"; + fi +else + echo "$FILE is not a *.tex file." +fi diff --git a/scripts/pdflatex.sh b/scripts/pdflatex.sh new file mode 100755 index 0000000..4870896 --- /dev/null +++ b/scripts/pdflatex.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +FILEDIRNAME=${1%/*} +FILE=${1##*/} +echo "fileDirname : $FILEDIRNAME" +echo "file : $FILE" + +if [ ${FILE: -4} == ".tex" ]; then + cd "$FILEDIRNAME" + pdflatex -synctex=1 -interaction=nonstopmode -output-directory="$FILEDIRNAME" "$FILE" > ~/.vscode/.pdflatex_log + if [ $? == 0 ]; then # check success status (return value) of the last command (pdflatex) + echo -e "\033[32mCreated \"${FILE%.*}.pdf\" successfully.\033[0m"; + # lsof -- "${FILE%.*}.pdf" > /dev/null; # check if .pdf file if allready opened + # if [ $? != 0 ]; then + # ( nohup evince "${FILE%.*}.pdf" > /dev/null; exit; ) # open the created .pdf + # fi + else + cat ~/.vscode/.pdflatex_log + echo -e "\033[31mERROR: Compiling \"${FILE}\" failed.\033[0m"; + fi +else + echo "$FILE is not a *.tex file." +fi diff --git a/snippets/LaTeX.json b/snippets/LaTeX.json index d9a2191..c5cb439 100644 --- a/snippets/LaTeX.json +++ b/snippets/LaTeX.json @@ -1,13 +1,13 @@ { - "begin-end": { - "prefix": "\\begin", - "body": [ - "\\begin{${1:displaymath}}", - "\t$0", - "\\end{$1}" - ], - "description": "A Begin/End Block" - }, +// "begin-end": { +// "prefix": "\\begin", +// "body": [ +// "\\begin{${1:displaymath}}", +// "\t$0", +// "\\end{$1}" +// ], +// "description": "A Begin/End Block" +// }, "environment_tikz": { "prefix": "environment_tikz", "body": [ diff --git a/src/commands.ts b/src/commands.ts new file mode 100644 index 0000000..54e4dfe --- /dev/null +++ b/src/commands.ts @@ -0,0 +1,50 @@ +import * as vscode from 'vscode'; +import * as child_process from 'child_process'; + +export default { + // pdflatex -synctex=1 -interaction=nonstopmode -output-directory="$FILEDIRNAME" "$FILE" > ~/.vscode/.pdflatex_log + + latex_pdflatex: function latex_pdflatex(textEditor: vscode.TextEditor, textEditorEdit: vscode.TextEditorEdit): void { + var document: vscode.TextDocument = textEditor.document; + var fileDir: string = document.fileName.substring(0, document.fileName.lastIndexOf('/')); + + document.save(); // save the document before compile + child_process.exec("pdflatex -synctex=1 -interaction=nonstopmode -output-directory=" + fileDir + " " + document.fileName, + { cwd: fileDir }, // set the working directory + (error, stdout, stderr) => { + if (error) { + vscode.window.showErrorMessage("pdflatex Failed: " + error.message + ", " + stdout); + } else { + vscode.window.setStatusBarMessage("Created File: " + document.fileName.replace('.tex', '.pdf'), 5000); + } + } + ); + }, + + // latex_pdflatex: function latex_pdflatex(textEditor: vscode.TextEditor, textEditorEdit: vscode.TextEditorEdit): void { + // textEditor.document.save(); + // child_process.exec( + // "echo $(" + this.extensionPath + "/scripts/pdflatex.sh \"" + textEditor.document.fileName + "\")", + // (error: Error, stdout: string, stderr: string) => { + // if (error) { + // vscode.window.showErrorMessage("pdflatex Failed: " + error.message + ", " + stdout); + // } else { + // vscode.window.setStatusBarMessage("Created File: " + textEditor.document.fileName.replace('.tex', '.pdf'), 5000); + // } + // } + // ); + // }, + latex_makeindex: function latex_makeindex(textEditor: vscode.TextEditor, textEditorEdit: vscode.TextEditorEdit): void { + textEditor.document.save(); + child_process.exec( + "echo $(" + this.extensionPath + "/scripts/makeindex.sh \"" + textEditor.document.fileName + "\")", + (error: Error, stdout: string, stderr: string) => { + if (error) { + vscode.window.showErrorMessage("makeindex Failed: " + error.message + ", " + stdout); + } else { + vscode.window.setStatusBarMessage("Index Created: " + textEditor.document.fileName.replace('.tex', '.idx'), 5000); + } + } + ); + } +} diff --git a/src/completionItemProvider.ts b/src/completionItemProvider.ts index ca881e0..86d812d 100644 --- a/src/completionItemProvider.ts +++ b/src/completionItemProvider.ts @@ -5,305 +5,295 @@ import text_symbols from '../dictionary/text_symbols'; import math_symbols from '../dictionary/math_symbols'; import package_symbols from '../dictionary/package_symbols'; import environment_symbols from '../dictionary/environment_symbols'; +import documentclass_symbols from '../dictionary/documentclass_symbols'; import tikz_symbols from '../dictionary/tikz_symbols'; import parameter_dictionary from '../dictionary/parameter_dictionary'; import * as child_process from 'child_process'; function convertToItemKind(type: latex_types): vscode.CompletionItemKind { - switch (type) { - case latex_types.symbol: - return vscode.CompletionItemKind.Variable; - case latex_types.function: - return vscode.CompletionItemKind.Function; - case latex_types.environment: - return vscode.CompletionItemKind.Interface; - case latex_types.package: - return vscode.CompletionItemKind.Module; - case latex_types.keyword: - return vscode.CompletionItemKind.Keyword; - case latex_types.parameter: - return vscode.CompletionItemKind.Value; - case latex_types.snippet: - return vscode.CompletionItemKind.Snippet; - default: - return vscode.CompletionItemKind.Property; - } + switch (type) { + case latex_types.symbol: + return vscode.CompletionItemKind.Variable; + case latex_types.function: + return vscode.CompletionItemKind.Function; + case latex_types.environment: + return vscode.CompletionItemKind.Interface; + case latex_types.package: + return vscode.CompletionItemKind.Module; + case latex_types.keyword: + return vscode.CompletionItemKind.Keyword; + case latex_types.parameter: + return vscode.CompletionItemKind.Value; + case latex_types.snippet: + return vscode.CompletionItemKind.Snippet; + default: + return vscode.CompletionItemKind.Property; + } } function createCompletionItem(label: string, sym_def: Object, match?: string, range?: vscode.Range): vscode.CompletionItem { - var item = new vscode.CompletionItem(label, convertToItemKind(sym_def["kind"])); - if (sym_def["detail"]) { - item.detail = sym_def["detail"]; - } - if (sym_def["documentation"]) { - item.documentation = sym_def["documentation"]; - } - if (sym_def["insertText"]) { - if (sym_def["insertText"].indexOf("$") > -1) { - item.insertText = new vscode.SnippetString(sym_def["insertText"]); - } else { - item.insertText = sym_def["insertText"]; - } - } - if (match) { // if the sortText ins't set, default behaviour ist sorting by label - let index = label.indexOf(match); - item.sortText = (index > -1 ? index : "") + label; - } - if (range) { // if no range is set, no replacement will be done just adding the insertText (or label) at cursor position - item.range = range; - } - return item; + var item = new vscode.CompletionItem(label, convertToItemKind(sym_def["kind"])); + if (sym_def["detail"]) { + item.detail = sym_def["detail"]; + } + if (sym_def["documentation"]) { + item.documentation = sym_def["documentation"]; + } + if (sym_def["insertText"]) { + if (sym_def["insertText"].indexOf("$") > -1) { + item.insertText = new vscode.SnippetString(sym_def["insertText"]); + } else { + item.insertText = sym_def["insertText"]; + } + } + if (match) { // if the sortText ins't set, default behaviour ist sorting by label + let index = label.indexOf(match); + item.sortText = (index > -1 ? index : "") + label; + } + if (range) { // if no range is set, no replacement will be done just adding the insertText (or label) at cursor position + item.range = range; + } + return item; } function fillSymbols(symbolsCollection: vscode.CompletionItem[], symbolsDefinition: Object, match?: string, position?: vscode.Position): void { - if (match) { // if a match is provided, add a sortText for preordering by match index - if (position) { - var range = new vscode.Range(new vscode.Position(position.line, position.character - match.length), position); - } else { - throw new Error("[ CompletionItemProvider | fillSymbols ] Parameter \"position\" not supplied. If parameter \"match\" is supplied, \"position\" has to be supplied to!"); - } - } - for (var key in symbolsDefinition) { - if (match && !key.includes(match)) { continue; } // if no match is provided, ignore filtering otherwise ignore the symbol if the match isn't contained - var sym_def = symbolsDefinition[key]; - symbolsCollection.push(createCompletionItem(key, sym_def, match, range)); - if (sym_def.additionalInserts instanceof Array) { - for (var i = 0; i < sym_def.additionalInserts.length; i++) { - var additionalInsert = sym_def.additionalInserts[i]; - if (typeof additionalInsert === "string") { - sym_def.insertText = additionalInsert; - symbolsCollection.push(createCompletionItem(additionalInsert, sym_def, match, range)); - } else if (typeof additionalInsert === "object") { - sym_def.insertText = additionalInsert["insertText"]; - if (additionalInsert.hasOwnProperty("kind")) { - sym_def.kind = additionalInsert.kind; - } - symbolsCollection.push(createCompletionItem(additionalInsert["label"], sym_def, match, range)); - } else { - throw new Error("[ CompletionItemProvider | fillSymbols ] A additionalInsert instance isn't well defined: " + additionalInsert); - } - } - } - } + if (match) { // if a match is provided, add a sortText for preordering by match index + if (position) { + var range = new vscode.Range(new vscode.Position(position.line, position.character - match.length), position); + } else { + throw new Error("[ CompletionItemProvider | fillSymbols ] Parameter \"position\" not supplied. If parameter \"match\" is supplied, \"position\" has to be supplied to!"); + } + } + for (var key in symbolsDefinition) { + if (match && !key.includes(match)) { continue; } // if no match is provided, ignore filtering otherwise ignore the symbol if the match isn't contained + var sym_def = symbolsDefinition[key]; + symbolsCollection.push(createCompletionItem(key, sym_def, match, range)); + if (sym_def.additionalInserts instanceof Array) { + for (var i = 0; i < sym_def.additionalInserts.length; i++) { + var additionalInsert = sym_def.additionalInserts[i]; + if (typeof additionalInsert === "string") { + sym_def.insertText = additionalInsert; + symbolsCollection.push(createCompletionItem(additionalInsert, sym_def, match, range)); + } else if (typeof additionalInsert === "object") { + sym_def.insertText = additionalInsert["insertText"]; + if (additionalInsert.hasOwnProperty("kind")) { + sym_def.kind = additionalInsert.kind; + } + symbolsCollection.push(createCompletionItem(additionalInsert["label"], sym_def, match, range)); + } else { + throw new Error("[ CompletionItemProvider | fillSymbols ] A additionalInsert instance isn't well defined: " + additionalInsert); + } + } + } + } } export default class Provider implements vscode.CompletionItemProvider { - private preamble_symbols: vscode.CompletionItem[]; - private text_symbols: vscode.CompletionItem[]; - private math_symbols: vscode.CompletionItem[]; - private package_symbols: vscode.CompletionItem[]; - private environment_symbols: vscode.CompletionItem[]; - private tikz_symbols: vscode.CompletionItem[]; + private preamble_symbols: vscode.CompletionItem[]; + private text_symbols: vscode.CompletionItem[]; + private math_symbols: vscode.CompletionItem[]; + private package_symbols: vscode.CompletionItem[]; + private documentclass_symbols: vscode.CompletionItem[]; + private environment_symbols: vscode.CompletionItem[]; + private tikz_symbols: vscode.CompletionItem[]; - private parameter_dictionary: Object; + private parameter_dictionary: Object; - private environment_type_dict = { - "displaymath": "math", "equation": "math", "eqnarray": "math", "align": "math", "align*": "math", - "multline": "math", "multline*": "math", "gather": "math", "gather*": "math", "split": "math", "split*": "math", - "tikzpicture": "tikz", - "document": "text" - }; + private environment_type_dict = { + "displaymath": "math", "equation": "math", "eqnarray": "math", "align": "math", "align*": "math", + "multline": "math", "multline*": "math", "gather": "math", "gather*": "math", "split": "math", "split*": "math", + "tikzpicture": "tikz", + "document": "text" + }; constructor() { - // initialize Collections - this.preamble_symbols = new Array(); - this.text_symbols = new Array(); - this.math_symbols = new Array(); - this.package_symbols = new Array(); - this.environment_symbols = new Array(); - this.tikz_symbols = new Array(); - // fill the collections from the LaTeX symbols definitions - fillSymbols(this.preamble_symbols, preamble_symbols); - fillSymbols(this.text_symbols, text_symbols); - fillSymbols(this.math_symbols, math_symbols); - fillSymbols(this.package_symbols, package_symbols); - fillSymbols(this.environment_symbols, environment_symbols); - fillSymbols(this.tikz_symbols, tikz_symbols); - this.parameter_dictionary = parameter_dictionary; - } - - dispose() { } - - private getEnvironmentType(document: vscode.TextDocument, line_before_pos: string, position: vscode.Position): string { - { // check for inline math - let count = 0; - let i: number; - for (i = 0; i < line_before_pos.length; i++) { - if (line_before_pos[i] === "$") { - count++; // count number of inline math beginnings and endings - } - } - if (count % 2 === 1) { // 2 $ characters represent a closed inline math environment -> odd number is in inline math - return "math"; // inside inline math -> environment type is math - } - } - // search environment beginings and endings and return type according to environment type - var begin_index = -1; - var end_index = -1; - var environment: string; - for (var i = position.line; i >= 0; i--) { // iterate over lines from the current line (position) to the top of he document - var line = document.lineAt(i); // get line with linenumber i (0 based) - if (line.isEmptyOrWhitespace) { continue; } // consistency check - var line_text = line.text; // get the current line as string - while (line_text.length > 6) { // More then "\\end{" and "}" characters are neccessary for a usefull accessment - begin_index = line_text.lastIndexOf("\\begin{"); - end_index = line_text.lastIndexOf("\\end{"); - if (begin_index > end_index) { - let environment = line_text.substring(begin_index + 7, line_text.indexOf("}", begin_index + 7)); - if (this.environment_type_dict.hasOwnProperty(environment)) { - return this.environment_type_dict[environment]; // environment beginning found -> return environment type - } - } else if (end_index > begin_index) { - let environment = line_text.substring(end_index + 5, line_text.indexOf("}", end_index + 5)); - if (this.environment_type_dict.hasOwnProperty(environment)) { - return "text"; // environment ending found -> in text area - } - } else { - break; - } - line_text = line_text.substring(0, begin_index > end_index ? begin_index : end_index); - } - } - return; // nothing found, return to default behaviour - } - - private filterParameters(symbol_name: string, parameter_match: string, position: vscode.Position): vscode.CompletionItem[] { - if (this.parameter_dictionary.hasOwnProperty(symbol_name)) { - var completionItems = new Array(); - fillSymbols(completionItems, this.parameter_dictionary[symbol_name], parameter_match, position); - return completionItems; - } - return []; - } - - private searchAndCreateLableSymbols(document: vscode.TextDocument, symbol_lable: string, position: vscode.Position): vscode.CompletionItem[] { - var completionItems = new Array(); - for (var i = 0; i < document.lineCount; i++) { - var line = document.lineAt(i); - if (line.isEmptyOrWhitespace) { continue; } - var line_text = line.text; - var index_start = line_text.indexOf("\\label{") + 7; // add 7 to considure the length of "\label{" - if (index_start > 6) { // index_start returns > -1 iff substring was found, adding 7 => 6 - var index_end = line_text.indexOf("}", index_start); - if (index_end > -1) { - completionItems.push(new vscode.CompletionItem(line_text.substring(index_start, index_end), vscode.CompletionItemKind.Reference)); - } - } - } - return completionItems; - } - - private filterSymbols(symbolsCollection: vscode.CompletionItem[], match: string, position: vscode.Position): vscode.CompletionItem[] { - if (!match || match.length === 0) { // no filtering neccessary (empty string is substring of all lables) -> return all - return symbolsCollection; - } - var filtert_symbols = new Array(); - var range = new vscode.Range(new vscode.Position(position.line, position.character - match.length), position); - for (var i = 0; i < symbolsCollection.length; i++) { - var item = symbolsCollection[i]; - var clonedItem; - if (item.label.includes(match)) { - clonedItem = new vscode.CompletionItem(item.label, item.kind); - if (item.documentation) { - clonedItem.documentation = item.documentation; - } - if (item.insertText) { - clonedItem.insertText = item.insertText; - } - if (range) { - clonedItem.range = range; - } - clonedItem.filterText = match; - clonedItem.sortText = item.label.indexOf(match) + item.label; - filtert_symbols.push(clonedItem); - } - } - return filtert_symbols; - } - - - // // var p: Promise = new Promise (function (resolve: (str: string) => void, reject: (str: string) => void) { - // // const argumentOfThen: string = "hello from Promise"; - // // resolve(argumentOfThen); - // // }).then((result) => { - // // return result; - // // }); - // /** - // * Encapsulates results from syncrone calculations in a promise and passes them throuw immediately - // * @param result The return value from .then's function - // */ - // private promiseResult(result: vscode.CompletionItem[]): Thenable { - // return new Promise((resolve, reject) => { resolve(result); }).then((res) => res); - // } - - private getFileNames(path: string, resolve: (completionItems: vscode.CompletionItem[]) => void, reject: (message: string) => void): void { - child_process.exec("ls " + path + " -t", (error: Error, stdout: string, stderr: string) => { - var fileNames = stdout.split("\n"); - var completionItems = new Array(); - for (var i = 0; i < fileNames.length; i++) { - completionItems.push(new vscode.CompletionItem(fileNames[i], vscode.CompletionItemKind.File)); - } - resolve(completionItems); - }); - } - - provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): Thenable { - return new Promise((resolve, reject) => { - var line = document.lineAt(position); - if (line.isEmptyOrWhitespace) { - return resolve([]); - } - var line_text = line.text; - var line_before_pos = line_text.substring(0, position.character).trim(); - - var start_index: number; - var end_index: number; - var symbol_lable: string; - var symbol_parameter: string; - if ((start_index = line_before_pos.lastIndexOf("\\") + 1) > 0) { - if ((end_index = line_before_pos.indexOf("{", start_index)) > -1) { - symbol_lable = line_before_pos.substring(start_index, end_index); - symbol_parameter = line_before_pos.substring(end_index + 1); - if ((end_index = symbol_lable.indexOf("[")) > -1) { // check for optional symbol parameters and ignore them if present - symbol_lable = symbol_lable.substring(0, end_index); - } - switch (symbol_lable) { - case "begin": - case "end": - return resolve(this.filterSymbols(this.environment_symbols, symbol_parameter, position)); - case "ref": - case "eqref": - case "pageref": - return resolve(this.searchAndCreateLableSymbols(document, symbol_parameter, position)); - case "usepackage": // provide package symbols by first all usepackage parameters before the last "," - return resolve(this.filterSymbols(this.package_symbols, symbol_parameter.substring(symbol_parameter.lastIndexOf(",") + 1).trim(), position)); - case "input": - case "include": - case "includegraphics": - return this.getFileNames(symbol_parameter, resolve, reject); // runs async -> let getFileNames resolve / reject the promise - default: // default to NO suggestions - return resolve([]); - } - } else if ((end_index = line_before_pos.indexOf("[", start_index)) > -1) { - symbol_lable = line_before_pos.substring(start_index, end_index); - symbol_parameter = line_before_pos.substring(end_index + 1) - return resolve(this.filterParameters(symbol_lable, symbol_parameter.substring(symbol_parameter.lastIndexOf(",") + 1).trim(), position)); - } else { - symbol_lable = line_before_pos.substring(start_index); - switch (this.getEnvironmentType(document, line_before_pos, position)) { - case "math": - return resolve(this.filterSymbols(this.math_symbols, symbol_lable, position)); - case "tikz": - return resolve(this.filterSymbols(this.tikz_symbols, symbol_lable, position)); - case "text": - return resolve(this.filterSymbols(this.text_symbols, symbol_lable, position)); - default: - return resolve(this.filterSymbols(this.preamble_symbols, symbol_lable, position)); - } - } - } - resolve([]); - }).then((res) => res); + // initialize Collections + this.preamble_symbols = new Array(); + this.text_symbols = new Array(); + this.math_symbols = new Array(); + this.package_symbols = new Array(); + this.environment_symbols = new Array(); + this.documentclass_symbols = new Array(); + this.tikz_symbols = new Array(); + // fill the collections from the LaTeX symbols definitions + fillSymbols(this.preamble_symbols, preamble_symbols); + fillSymbols(this.text_symbols, text_symbols); + fillSymbols(this.math_symbols, math_symbols); + fillSymbols(this.package_symbols, package_symbols); + fillSymbols(this.environment_symbols, environment_symbols); + fillSymbols(this.documentclass_symbols, documentclass_symbols); + fillSymbols(this.tikz_symbols, tikz_symbols); + this.parameter_dictionary = parameter_dictionary; } -} \ No newline at end of file + + dispose() { } + + private getEnvironmentType(document: vscode.TextDocument, line_before_pos: string, position: vscode.Position): string { + { // check for inline math + let count = 0; + let i: number; + for (i = 0; i < line_before_pos.length; i++) { + if (line_before_pos[i] === "$") { + count++; // count number of inline math beginnings and endings + } + } + if (count % 2 === 1) { // 2 $ characters represent a closed inline math environment -> odd number is in inline math + return "math"; // inside inline math -> environment type is math + } + } + // search environment beginings and endings and return type according to environment type + var begin_index = -1; + var end_index = -1; + var environment: string; + for (var i = position.line; i >= 0; i--) { // iterate over lines from the current line (position) to the top of he document + var line = document.lineAt(i); // get line with linenumber i (0 based) + if (line.isEmptyOrWhitespace) { continue; } // consistency check + var line_text = line.text; // get the current line as string + while (line_text.length > 6) { // More then "\\end{" and "}" characters are neccessary for a usefull accessment + begin_index = line_text.lastIndexOf("\\begin{"); + end_index = line_text.lastIndexOf("\\end{"); + if (begin_index > end_index) { + let environment = line_text.substring(begin_index + 7, line_text.indexOf("}", begin_index + 7)); + if (this.environment_type_dict.hasOwnProperty(environment)) { + return this.environment_type_dict[environment]; // environment beginning found -> return environment type + } + } else if (end_index > begin_index) { + let environment = line_text.substring(end_index + 5, line_text.indexOf("}", end_index + 5)); + if (this.environment_type_dict.hasOwnProperty(environment)) { + return "text"; // environment ending found -> in text area + } + } else { + break; + } + line_text = line_text.substring(0, begin_index > end_index ? begin_index : end_index); + } + } + return; // nothing found, return to default behaviour + } + + private filterParameters(symbol_name: string, parameter_match: string, position: vscode.Position): vscode.CompletionItem[] { + if (this.parameter_dictionary.hasOwnProperty(symbol_name)) { + var completionItems = new Array(); + fillSymbols(completionItems, this.parameter_dictionary[symbol_name], parameter_match, position); + return completionItems; + } + return []; + } + + private searchAndCreateLableSymbols(document: vscode.TextDocument, symbol_lable: string, position: vscode.Position): vscode.CompletionItem[] { + var completionItems = new Array(); + for (var i = 0; i < document.lineCount; i++) { + var line = document.lineAt(i); + if (line.isEmptyOrWhitespace) { continue; } + var line_text = line.text; + var index_start = line_text.indexOf("\\label{") + 7; // add 7 to considure the length of "\label{" + if (index_start > 6) { // index_start returns > -1 iff substring was found, adding 7 => 6 + var index_end = line_text.indexOf("}", index_start); + if (index_end > -1) { + completionItems.push(new vscode.CompletionItem(line_text.substring(index_start, index_end), vscode.CompletionItemKind.Reference)); + } + } + } + return completionItems; + } + + private filterSymbols(symbolsCollection: vscode.CompletionItem[], match: string, position: vscode.Position): vscode.CompletionItem[] { + if (!match || match.length === 0) { // no filtering neccessary (empty string is substring of all lables) -> return all + return symbolsCollection; + } + var filtert_symbols = new Array(); + var range = new vscode.Range(new vscode.Position(position.line, position.character - match.length), position); + for (var i = 0; i < symbolsCollection.length; i++) { + var item = symbolsCollection[i]; + var clonedItem; + if (item.label.includes(match)) { + clonedItem = new vscode.CompletionItem(item.label, item.kind); + if (item.documentation) { + clonedItem.documentation = item.documentation; + } + if (item.insertText) { + clonedItem.insertText = item.insertText; + } + if (range) { + clonedItem.range = range; + } + clonedItem.filterText = match; + clonedItem.sortText = item.label.indexOf(match) + item.label; + filtert_symbols.push(clonedItem); + } + } + return filtert_symbols; + } + + private getFileNames(path: string, resolve: (completionItems: vscode.CompletionItem[]) => void, reject: (message: string) => void): void { + child_process.exec("ls " + path + " -t", (error: Error, stdout: string, stderr: string) => { + var fileNames = stdout.split("\n"); + var completionItems = new Array(); + for (var i = 0; i < fileNames.length; i++) { + completionItems.push(new vscode.CompletionItem(fileNames[i], vscode.CompletionItemKind.File)); + } + resolve(completionItems); + }); + } + + provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): Thenable { + return new Promise((resolve, reject) => { + var line = document.lineAt(position); + if (line.isEmptyOrWhitespace) { + return resolve([]); + } + var line_text = line.text; + var line_before_pos = line_text.substring(0, position.character).trim(); + + var start_index, end_index: number; + var symbol_lable, symbol_parameter: string; + if ((start_index = line_before_pos.lastIndexOf("\\") + 1) > 0) { + if ((end_index = line_before_pos.indexOf("{", start_index)) > -1) { + symbol_lable = line_before_pos.substring(start_index, end_index); + symbol_parameter = line_before_pos.substring(end_index + 1); + if ((end_index = symbol_lable.indexOf("[")) > -1) { // check for optional symbol parameters and ignore them + symbol_lable = symbol_lable.substring(0, end_index); + } + switch (symbol_lable) { + case "begin": + case "end": + return resolve(this.filterSymbols(this.environment_symbols, symbol_parameter, position)); + case "ref": + case "eqref": + case "pageref": + return resolve(this.searchAndCreateLableSymbols(document, symbol_parameter, position)); + case "usepackage": // provide package symbols by first all usepackage parameters before the last "," + return resolve(this.filterSymbols(this.package_symbols, symbol_parameter.substring(symbol_parameter.lastIndexOf(",") + 1).trim(), position)); + case "documentclass": + return resolve(this.filterSymbols(this.documentclass_symbols, symbol_parameter, position)); + case "input": + case "include": + case "includegraphics": + case "lstinputlisting": + return this.getFileNames(symbol_parameter, resolve, reject); // runs async -> let getFileNames resolve / reject the promise + default: // default to NO suggestions + return resolve([]); + } + } else if ((end_index = line_before_pos.indexOf("[", start_index)) > -1) { + symbol_lable = line_before_pos.substring(start_index, end_index); + symbol_parameter = line_before_pos.substring(end_index + 1) + return resolve(this.filterParameters(symbol_lable, symbol_parameter.substring(symbol_parameter.lastIndexOf(",") + 1).trim(), position)); + } else { + symbol_lable = line_before_pos.substring(start_index); + switch (this.getEnvironmentType(document, line_before_pos, position)) { + case "math": + return resolve(this.filterSymbols(this.math_symbols, symbol_lable, position)); + case "tikz": + return resolve(this.filterSymbols(this.tikz_symbols, symbol_lable, position)); + case "text": + return resolve(this.filterSymbols(this.text_symbols, symbol_lable, position)); + default: + return resolve(this.filterSymbols(this.preamble_symbols, symbol_lable, position)); + } + } + } + resolve([]); + }).then((res) => res); + } +} diff --git a/src/extension.ts b/src/extension.ts index 2570505..c1a79b6 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -2,14 +2,29 @@ // Import the module and reference it with the alias vscode in your code below import * as vscode from 'vscode'; import CompletionItemProvider from './completionItemProvider'; +import Commands from './commands'; // this method is called when your extension is activated // your extension is activated the very first time the command is executed export function activate(context: vscode.ExtensionContext) { - // Register the Completion Item Provider - context.subscriptions.push(vscode.languages.registerCompletionItemProvider( - [{ language: 'latex'}], // document selector - new CompletionItemProvider(), // A Complete Item Provider instance - '\\', '{', '[' //, '=' // Characters to trigger an completion suggestion - )); + // Register Build Commands + // The Command was defined in package.json and the commandId parameter has + // to be equal to the 'command' field in the package.json file + context.subscriptions.push(vscode.commands.registerTextEditorCommand( + 'latex.pdflatex', + Commands.latex_pdflatex, + { extensionPath: context.extensionPath } + )); + context.subscriptions.push(vscode.commands.registerTextEditorCommand( + 'latex.makeindex', + Commands.latex_makeindex, + { extensionPath: context.extensionPath } + )); + + // Register the Completion Item Provider + context.subscriptions.push(vscode.languages.registerCompletionItemProvider( + [{ language: 'latex' }], // document selector + new CompletionItemProvider(), // A Complete Item Provider instance + '\\', '{', '[' //, '=' // Characters to trigger an completion suggestion + )); }