Skip to content

Commit

Permalink
Fixed ruby-calc-indent
Browse files Browse the repository at this point in the history
  • Loading branch information
sl33pii committed Oct 17, 2024
1 parent 9de1041 commit 6e1d22a
Showing 1 changed file with 71 additions and 12 deletions.
83 changes: 71 additions & 12 deletions extensions/ruby-mode/ruby-mode.lisp
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
(defpackage :lem-ruby-mode
(:use :cl :lem :lem/language-mode :lem/language-mode-tools)
(:import-from :lem-js-mode
:get-line-indent
:move-to-previous-line)
(:export :ruby-mode))

(in-package :lem-ruby-mode)
Expand All @@ -10,7 +13,8 @@
"end" "next"
"redo" "retry"
"return" "self" "super"
"undef" "yield"))
"undef" "yield" "private"
"public" "protected"))

(defvar *ruby-block-beg-keywords*
'("class" "module" "def" "case" "for" "begin" "do"))
Expand All @@ -24,6 +28,19 @@
(defvar *ruby-block-op-keywords*
'("and" "or" "not"))

(defvar *ruby-block-start*
"(^|\\s)(def|class|module|loop|for|begin|do)\\b")

(defvar *ruby-multiline-block-start*
"^\\s*(if|then|until|unless|while)\\b")

(defvar *ruby-block-end*
"(^|\\s)(end)\\b")

;; Regex to check if a line contains an opening/closing parenthesis/bracket
(defvar *paren-bracket-open-close-pattern* "^.*[\(\[\{].*[\\}\\)\\]].*$")
(defvar *paren-bracket-open-pattern* "^.*[\(\[\{].*$")
(defvar *paren-bracket-close-pattern* "^.*[\\)\\]\\}].*$")

(defvar *ruby-boolean-literals*
'("true" "false"))
Expand All @@ -33,12 +50,9 @@

;; From: https://www.rubyguides.com/2018/07/ruby-operators/
(defvar *ruby-operators*
'(
"+" "*" "++" "--" "<>" "||" "&&" "!"
'("+" "*" "++" "--" "<>" "||" "&&" "!"
"==" "!=" "===" "!==" ">=" "<=" "<=>"
"?" "~" "<<" ">>" "%" "|"
))

"?" "~" "<<" ">>" "%" "|"))

(defun tokens (boundary strings)
(let ((alternation
Expand Down Expand Up @@ -87,19 +101,21 @@
(set-syntax-parser table tmlanguage)
table))


(define-major-mode ruby-mode language-mode
(:name "Ruby"
:syntax-table *ruby-syntax-table*
:mode-hook *ruby-mode-hook*)
(setf (variable-value 'enable-syntax-highlight) t
(variable-value 'indent-tabs-mode) nil
(variable-value 'tab-width) 2
(variable-value 'line-comment) "#"
(variable-value 'beginning-of-defun-function) 'beginning-of-defun
(variable-value 'end-of-defun-function) 'end-of-defun))
(variable-value 'indent-tabs-mode) nil
(variable-value 'calc-indent-function) 'ruby-calc-indent
(variable-value 'tab-width) 2
(variable-value 'line-comment) "#"
(variable-value 'beginning-of-defun-function) 'beginning-of-defun
(variable-value 'end-of-defun-function) 'end-of-defun))

(defun beginning-of-defun (point n)
(loop :with regex = "^(def|class|module|case|for|begin|do|if|unless|while|until)?"
(loop :with regex = *ruby-block-start*
:repeat n
:do (search-backward-regexp point regex)))

Expand All @@ -112,4 +128,47 @@
(line-start p)
(move-point point p)))

(defun open-parens-bracket (start end)
(and (not (search-backward-regexp end *paren-bracket-open-close-pattern* start))
(search-backward-regexp end *paren-bracket-open-pattern* start)))


(defun close-parens-bracket (start end)
(and (not (search-backward-regexp end *paren-bracket-open-close-pattern* start))
(search-backward-regexp end *paren-bracket-close-pattern* start)))

(defun ruby-calc-indent (point)
(with-point ((prev point))
(move-to-previous-line prev)
(with-point ((p point))
(if (start-buffer-p (line-start p))
(return-from ruby-calc-indent 0)))
(let ((tab-width (variable-value 'tab-width :default point))
(column (length (get-line-indent prev))))
(when (in-string-or-comment-p point)
(with-point ((p point))
(back-to-indentation p)
(return-from ruby-calc-indent (point-column p))))

(with-point ((p point))
(when (move-to-previous-line p)
(with-point ((start p)
(end p))
(line-start start)
(line-end end)
(when (or (search-backward-regexp end *ruby-block-start* start)
(search-backward-regexp end *ruby-multiline-block-start* start)
(open-parens-bracket start end))
(return-from ruby-calc-indent (incf column tab-width))))))

(with-point ((p point)
(start point)
(end point))
(line-start start)
(line-end end)
(if (or (close-parens-bracket start end)
(search-forward-regexp p *ruby-block-end* (line-end end)) )
(decf column tab-width)))
column)))

(define-file-type ("rb" "rspec" "Gemfile") ruby-mode)

0 comments on commit 6e1d22a

Please sign in to comment.