diff options
author | Kyle Meyer <kyle@kyleam.com> | 2015-03-07 18:24:03 -0500 |
---|---|---|
committer | Kyle Meyer <kyle@kyleam.com> | 2015-03-07 18:24:03 -0500 |
commit | 01d4fb81c6a5991f88bbe135ac8ef2e11e0f983c (patch) | |
tree | c450aca7a03de3098c1c5b01ad1bf6b83b43a778 /snakemake-mode.el | |
parent | e4db2a70f5cef845d4e80d43d071c875992a81cf (diff) | |
download | snakemake-mode-01d4fb81c6a5991f88bbe135ac8ef2e11e0f983c.tar.gz |
Rework indentation
- Change continued field values to support Python indentation. This
is useful when the value is using something like format (but only
applies to naked field keys).
- Don't move back to the start of the line when in a continued field
value.
- When on the first line of block, only indent to main offset.
- Move to current indentation if point is before it. Unless there is
one possible value for indentation, don't adjust indentation any
further.
Diffstat (limited to 'snakemake-mode.el')
-rw-r--r-- | snakemake-mode.el | 81 |
1 files changed, 63 insertions, 18 deletions
diff --git a/snakemake-mode.el b/snakemake-mode.el index cb928d5..51c5c30 100644 --- a/snakemake-mode.el +++ b/snakemake-mode.el @@ -122,13 +122,16 @@ rule blocks (or on a blank line directly below), call (python-indent-line-function))) (defun snakemake-indent-rule-line () - "Indent rule line. + "Indent line of a rule or subworkflow block. + +Indent according the the first case below that is true. - At the top of rule block Remove all indentation. -- At a rule field key ('input', 'output',...) +- At a rule field key ('input', 'output',...) or on the first + field line of the block Indent the line to `snakemake-indent-field-offset'. @@ -139,20 +142,27 @@ rule blocks (or on a blank line directly below), call - On any 'run' field value line except for the first value line. - Indent with `python-indent-line-function'. + Indent according to Python mode. + +- Before the current indentation + + Move point to the current indentation. - Otherwise - Alternate between no indentation, - `snakemake-indent-field-offset', and the column of the previous - field value." - (save-excursion - (let ((start-indent (current-indentation))) + Cycle between indenting to `snakemake-indent-field-offset', + indenting to the column of the previous field value. If within + a field value for a naked field key, add a step that indents + according to Python mode." + (let ((start-col (current-column)) + (start-indent (current-indentation))) + (save-excursion (beginning-of-line) (cond ((looking-at-p (concat "^\\s-*" snakemake-rule-or-subworkflow-re)) (delete-horizontal-space)) - ((looking-at-p (concat "^\\s-*" snakemake-field-key-re)) + ((or (looking-at-p (concat "^\\s-*" snakemake-field-key-re)) + (snakemake-first-field-line-p)) (delete-horizontal-space) (indent-to snakemake-indent-field-offset)) ((snakemake-below-naked-field-p) @@ -161,17 +171,36 @@ rule blocks (or on a blank line directly below), call snakemake-indent-value-offset))) ((snakemake-run-field-line-p) (python-indent-line-function)) - ((< start-indent snakemake-indent-field-offset) - (delete-horizontal-space) - (indent-to snakemake-indent-field-offset)) - (t + ((>= start-col start-indent) (let ((prev-col (snakemake-previous-field-value-column))) (when prev-col - (delete-horizontal-space) - (when (< start-indent prev-col) - (indent-to prev-col)))))))) - (when (< (current-column) (current-indentation)) - (forward-to-indentation 0))) + (cond + ((and (snakemake-naked-field-line-p) + (or (and (= start-indent 0) + (not (looking-at-p "^\\s-*$"))) + (= start-indent prev-col))) + (let (last-command) + ;; ^ Don't let `python-indent-line' do clever things + ;; when indent command is repeated. + (python-indent-line-function)) + (when (= (current-column) start-indent) + (delete-horizontal-space) + (indent-to snakemake-indent-value-offset))) + ((= start-indent snakemake-indent-field-offset) + (delete-horizontal-space) + (indent-to prev-col)) + (t + (delete-horizontal-space) + (indent-to snakemake-indent-field-offset)))))))) + (when (< (current-column) (current-indentation)) + (forward-to-indentation 0)))) + +(defun snakemake-first-field-line-p () + "Return non-nil if point is on first field line of block." + (save-excursion + (forward-line -1) + (beginning-of-line) + (looking-at-p (concat snakemake-rule-or-subworkflow-re)))) (defun snakemake-in-rule-or-subworkflow-block-p () "Return non-nil if point is in block or on first blank line following one." @@ -191,6 +220,22 @@ rule blocks (or on a blank line directly below), call (beginning-of-line) (looking-at-p (concat snakemake-field-key-indented-re "\\s-*$")))) +(defun snakemake-naked-field-line-p () + "Return non-nil if point is on any line of naked field key. +This function assumes that point is in a rule or subworkflow +block (which includes being on a blank line immediately below a +block)." + (save-excursion + (let ((rule-start (save-excursion + (end-of-line) + (re-search-backward snakemake-rule-or-subworkflow-re + nil t)))) + (end-of-line) + (and (re-search-backward snakemake-field-key-indented-re + rule-start t) + (goto-char (match-end 0)) + (looking-at-p "\\s-*$"))))) + (defun snakemake-run-field-line-p () "Return non-nil if point is on any line below a run field key. This function assumes that point is in a rule or subworkflow |